Stefan S.
Stefan S.

Reputation: 4103

Why Does AffineTransform Scale When Rotating

It's probably more a math problem, but why does this method fail?

public void test() {
    AffineTransform transform = AffineTransform.getRotateInstance(1);

    System.out.println("scaleX = " + transform.getScaleX() + ", " + "scaleY = " + transform.getScaleY());

    Assert.assertEquals(1, transform.getScaleX(), 0.001); // fails
    Assert.assertEquals(1, transform.getScaleY(), 0.001); // fails, too
}

The output is: scaleX = 0.5403023058681398, scaleY = 0.5403023058681398

Just from looking at it I'd say the scaling should not change while rotating.

Upvotes: 0

Views: 492

Answers (2)

cello
cello

Reputation: 5486

Take the following example: You only scale along the x-axis. Now you rotate by 90 degrees. Anything drawn should now scale along the y-axis, and not the x-axis anymore due to the rotation. And there you have it: the scaling changed.

Upvotes: 0

ValtsBlukis
ValtsBlukis

Reputation: 468

The scaleX and scaleY values you are getting are actually cos(1 rad) which is correct.

They do not represent the scale of an object after applying affine transformation. As per this documentation, scaleX is the contribution of the initial X coordinate before transform to the final X coordinate after transform. Same goes for scaleY. It doesn't mean that x1 = x0*scaleX, but x1 = x0*scaleX + y0*m01y + m02.

To assert that there is no scaling done, you can get the matrix values of the transformation and get the determinant. If there is no scale or shear, the determinant will be 1. Furthermore the 2 components representing displacement should be 0.

double[] m = transform.getMatrix()
Assert.assertEquals(1, m[0]*m[4] - m[1]*m[3], 0.001)
Assert.assertEquals(0, m[2], 0.001);
Assert.assertEquals(0, m[5], 0.001);

Upvotes: 2

Related Questions