Tuesday, November 04, 2008

Rotating Image in a PaintListener

For those who have a better understanding of matrices and 2-D graphics this may sound strange but today I struggeled about 2 hours rotating an image in a PaintListener.

Let me first of explain the exercise I had to solve, then show you my solution and then maybe someone can point out a better one.

Exercise

Draw an Image at Point(50,50) in a Canvas which is rotated a variable angle.

The solution

Solveing this problem one can use a SWT-Transform to adjust the Graphics-Context looks straight forward but it took me like said 2 hours to wrap my head around the problem. The following function is the solution I came up with.

public void paintControl(PaintEvent e) {
GC gc = e.gc;
gc.setAdvanced(true);

Bounds b = image.getBounds();

Transform transform = new Transform(display);
// The rotation point is the center of the image
transform.translate(50 + b.width/2, 50 + b.height/2);
// Rotate
transform.rotate(45);
// Back to the orginal coordinate system
transform.translate(-50 - b.width/2, -50 - b.height/2);
gc.setTransform(transform);
gc.drawImage(image, 50, 50);
transform.dispose();
}

Is the solution right? Is there a better solution?

My skills are very very bad when it comes to matrices and 2-D graphics so the above solution to the problem might be completely wrong and only works by chance.

8 comments:

Anonymous said...

instead of

transform.translate(-50 - b.width/2, -50 - b.height/2);
gc.setTransform(transform);
gc.drawImage(image, 50, 50);

u could do:
gc.drawImage(image, - b.width/2, - b.height/2);

Heath said...

Your solution looks fine, Tom. In college, I did a big project full of affine transforms, and that's exactly how we would have done it.

Anonymous said...

The question really is why we dont have an api that does:
gc.rotate('center',45);

So many things are programmed today. I dont know what they are for.
And the basics still lack intelligence.

varioustoxins said...

That's the way to do it. If you look at the maths there are other ways to do it but it is much more complicated for no real gain. Also this scales up to higher dimensional models (including 3d structures) which can also be handled using the same center - rotate - restore strategy

Anonymous said...

public static void drawImage(final GC gc, final Image image, final Point center,
final Point offset, final float angle) {
if (image == null || image.isDisposed()) {
return;
}
if (gc == null || gc.isDisposed()) {
return;
}
final Transform t = new Transform(gc.getDevice());
t.translate(center.x, center.y);
t.rotate(angle);
gc.setTransform(t);
gc.drawImage(image, -offset.x, -offset.y);
t.dispose();
gc.setTransform(null);
}

Generic Viagra said...

Technology and computers is something that have never been my strong ability. I'm not cut out to be an expert in this fields.

online viagra for men said...

Hello,
This is really very interesting....
great information about "Rotating Images" Thanks very much for sharing it. Keep posting such an interesting information. Great work.

viagra for men

generic viagra online said...

Hello,

This is very nice article with great effective efforts. I appreciated a lot what you have done here... Good job! Keep posting.

Regards
Alexa