views:

311

answers:

3

I've got a set of Java2D calls that draw vectors on a graphics context. I'd like for the image to be doubled in size and then rotated 90 degrees.

I'm using the following code to do this:

Graphics2D g2 = // ... get graphics 2d somehow ...
AffineTransform oldTransform = g2.getTransform();
AffineTransform newTransform = (AffineTransform)oldTransform.clone();
newTransform.concatenate(AffineTransform.getTranslateInstance(x1, x2));
newTransform.concatenate(AffineTransform.getScaleInstance((double)newW/(double)iconW, (double)newH/(double)iconH));
newTransform.concatenate(AffineTransform.getRotateInstance(Math.toRadians(rotationAngle), (double)iconW/2.0d, (double)iconH/2.0d));
// ... do my drawing ...

This rotates and scales, however, the scale isn't applied the way I would like. It is as if it is rotated before scaling, thus making the image wider on the wrong axis.

Is there a better way to do this?

+1  A: 

Change the order in which you concatenate the transforms to control the order in which they are applied in the composite.

MarkusQ
+2  A: 

I believe those transforms are implemented like a stack - so the last transform is performed first. Try reversing the order of the rotate and scale transformations and you should get what you are looking for.

newTransform.concatenate(AffineTransform.getTranslateInstance(x1, x2));
newTransform.concatenate(AffineTransform.getRotateInstance(Math.toRadians(rotationAngle), (double)iconW/2.0d, (double)iconH/2.0d));
newTransform.concatenate(AffineTransform.getScaleInstance((double)newW/(double)iconW, (double)newH/(double)iconH));
Eric Petroelje
Ok, this works, but I don't understand it. Why is it ok to apply the translate first? Ie, if translate is first it happens first. But rotate happens after scale even when rotation is applied first? There's something there I'm not understanding.
jsight
Hard to explain exactly why the translate will still work correctly, but if you look at the underlying matrix math, you'll see why it makes sense.
Eric Petroelje
A: 

Rotations are always performed about the origin. In order to rotate about a certain point you must translate the points.

This page explains the maths behind what you're trying to do and show why transformations need to be applied in a certain order.

Ben S
The second and third arguments to getRotateInstance manage the transformation. This wasn't the same problem.
jsight