AffineTransform 클래스
AffineTransform 클래스
AffineTransform 클래스는 2D 좌표를 다른 2D 좌표로 선형 매핑을 수행해 선의 "직진성"과 "평행성"을 보존하는 2D 아핀 변환을 나타내요. 아핀 변환은 이동(translation), 스케일(scale), 뒤집기(flip), 회전(rotation), 전단(shear)의 시퀀스로 구성할 수 있어요.
본문
이런 좌표 변환은 마지막 행이 [ 0 0 1 ]로 암시된 3행×3열 행렬로 표현할 수 있어요. 이 행렬은 소스 좌표 (x,y)를 열 벡터로 간주하고 좌표 벡터를 행렬과 곱해서 대상 좌표 (x',y')로 변환해요.
public class AffineTransform
extends Object
implements Cloneable, Serializable
[ x'] [ m00 m01 m02 ] [ x ] [ m00x + m01y + m02 ]
[ y'] = [ m10 m11 m12 ] [ y ] = [ m10x + m11y + m12 ]
[ 1 ] [ 0 0 1 ] [ 1 ] [ 1 ]
90도 회전 처리
AffineTransform 클래스의 rotate 메서드 중 일부 변형에서는 라디안 단위의 회전 각도를 double 정밀도 인자로 지정해요. 이 메서드들은 약 90도의 회전(180, 270, 360도 배수 포함)을 특별히 처리해서, 사분면 회전을 더 효율적으로 처리해요.
90도는 라디안으로 PI/2인데, PI는 초월수(그래서 무리수)라서 90도의 배수를 라디안의 정확한 double 정밀도 값으로 정확히 표현하는 것은 불가능해요. 그 결과 90·180·270·360도 같은 사분면 회전을 이 값들로 정확히 기술하는 것은 이론적으로 불가능해요. double 정밀도 부동소수점 값은 0이 아닌 PI/2의 배수에 매우 가까이 갈 수 있지만, sine이나 cosine이 정확히 0.0, 1.0, -1.0이 될 만큼 가까워지진 못해요.
이를 최적으로 처리하기 위해 라디안으로 회전 각도를 받는 메서드는 사분면 회전으로 의도된 각도를 감지하려 시도해요. 이 메서드들은 Math.sin(theta) 또는 Math.cos(theta)가 정확히 1.0이나 -1.0을 반환하면 각도 theta를 사분면 회전으로 취급해요. 대략 Math.PI/2.0의 작은 배수 주변 0.00000121도(약 0.0000000211 라디안) 범위에 이 속성이 성립해요.
주요 메서드
translate(double, double)— 이동 변환을 결합해요.scale(double, double)— 스케일 변환을 결합해요.rotate(double)— 라디안 각도로 회전 변환을 결합해요.shear(double, double)— 전단 변환을 결합해요.concatenate(AffineTransform)/preConcatenate(AffineTransform)— 변환을 결합해요.transform(Point2D)/createTransformedShape(Shape)— 좌표·도형을 변환해요.inverse()— 역변환을 만들어요.getScaleX()/getTranslateX()등 — 행렬 요소를 조회해요.isIdentity()— 항등 변환인지 확인해요.
사용 예
그래픽 객체를 회전·이동·스케일할 때 Graphics2D.setTransform(AffineTransform)이나 transform 메서드로 사용해요. Font의 글리프 변환, TextLayout의 회전 등에도 사용돼요.