1. Member
Join Date
Feb 2011
Posts
3
Rep Power
0

## Rotating Rectangle about its Centre

Hi all,

I'm trying to get to grips with drawing graphics in Java at the moment so I've decided to try and draw a rectangle on the screen and allow the user to move and rotate it using keyboard keys.

I've been able to do most of it, but now I'm stuck on the rotation of the rectangle in that it doesn't rotate correctly as it rotates about a point in the screen (where the rectangle is initially drawn) and not its central point. It's a bit difficult to explain in text but if you imagine a rectangle being created at the centre of a clock face and then moved to the edge (at say 3) when you try and rotate the rectangle it pivots on the centre of the clock face and not its own centre.

Basically, I want to always rotate the rectangle about its centre point only. I understand that using the translate and rotate methods actually moves the whole co-ordinate system not just the rectangle so I guess my question is how after rotating and translating can I restore the coordinate system back to as it was before I did anything (translate, rotate)?

Here is my code:
Java Code:
```import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.*;

public class ShapeExample extends JPanel implements KeyListener {

int x;
int y;
double rotation;

public ShapeExample() {
setFocusable(true);
setDoubleBuffered(true);
}

@Override
public void paintComponent(Graphics g) {
AffineTransform saveTransform;
final Graphics2D g2 = (Graphics2D) g;

g.clearRect(0, 0, this.getWidth(), this.getHeight());

Rectangle rect = new Rectangle(20, 20);

g2.rotate(Math.toRadians(rotation), rect.height / 2, rect.width / 2);
g2.translate(x, y);

g2.draw(rect);

}

public static void main(String[] args) {
WindowUtilities.openInJFrame(new ShapeExample(), 380, 400);
}

public void keyTyped(KeyEvent e) {
}

/** Handle the key-pressed event from the text field. */
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_LEFT:
x = x - 5;
repaint();
break;
case KeyEvent.VK_RIGHT:
x = x + 5;
repaint();
break;
case KeyEvent.VK_UP:
y = y - 5;
repaint();
break;
case KeyEvent.VK_DOWN:
y = y + 5;
repaint();
break;
case KeyEvent.VK_X:
rotation++;
repaint();
break;
case KeyEvent.VK_Z:
rotation--;
repaint();
break;

}
}

public void keyReleased(KeyEvent e) {
}
}```

2. Moderator
Join Date
Jul 2010
Location
California
Posts
1,641
Rep Power
9
Take a look at the API for the rotate Graphics2D method you are using...it translates, rotates, and -translates. Shouldn't be a need to call translate again (edit: nevermind, I think I misunderstood your initial intent). To reverse the rotation for future draw calls, just call g2.rotate on the negative of the rotation magnitude from the first call.
Last edited by doWhile; 02-15-2011 at 12:20 AM.

3. Member
Join Date
Feb 2011
Posts
3
Rep Power
0
Originally Posted by doWhile
Take a look at the API for the rotate Graphics2D method you are using...it translates, rotates, and -translates. Shouldn't be a need to call translate again (edit: nevermind, I think I misunderstood your initial intent). To reverse the rotation for future draw calls, just call g2.rotate on the negative of the rotation magnitude from the first call.

So something like save the rotation variable before any rotation takes place i.e. originalRotation and then call the rotate method with the originalRotation as a parameter?

Originally Posted by Fubarable
Have you tried to use x and y and basic algebra to find the new center point of the rectangle?

I think I tried this by calling the rotate method and passing it the y and x values for the centre of the rectangle and it didn't work.
The way I understood the issue is the rectangle isn't actually moving its just the co-ordinate system that is and the rectangle remains fixed with regards to the co-ordinate system meaning the rectangles coordinates never actually change.
I was using this tutorial 2. Ordering which shows the x and y axis rotating.

I'm not that great at maths which is probably part of the reason I'm struggling with this! I appreciate the replies, thank you.

4. Senior Member
Join Date
Jan 2009
Posts
671
Rep Power
8
First, rotate by the amount you want. Then translate. The amount you need to translate is determined as follows:

- compute the distance, d, to the center of the rectangle from 0, d = sqrt((x+w/2)^2 + (y+h/2)^2)

- the amount of x translation is 2d*cos((pi-angle)/2)
- the amount of y translation is 2d*sin((pi-angle)/2)

(I might have the sign backward on one or both)
Last edited by toadaly; 02-15-2011 at 07:01 AM.

5. Member
Join Date
Feb 2011
Posts
3
Rep Power
0
It's been a while since I've worked on this but I was able to achieve the movement I wanted; which was get a rectangle to move in a certain direction, rotate about its centre and then move in the new direction. I did it by using an 'AffineTransform'. I applied the translate and rotate methods to the 'AffineTransform' and then set the Graphics component to this transform after both the translate and rotate methods had been called. Then finally calling the draw method on the rectangle.

I just have one last issue in that I don't fully understand the trigonometry i've used to compute the movement of the rectangle. I understand that movement in a certain direction (i.e. at a certain angle) can be defined by the rate of change of the x value of the object in relation to the y value of the object. What I don't understand is what the sin and cos functions are actually doing.

What I'm really asking for is an explanation of the formulas in toadalys post:

- the amount of x translation is 2d*cos((pi-angle)/2)
- the amount of y translation is 2d*sin((pi-angle)/2)

I've been reading about trigonometry with regards to right angle triangles but I don't get what the above is actually doing, specifically the '(pi-angle)/2' bit.

6. Senior Member
Join Date
Jan 2009
Posts
671
Rep Power
8
If you don't know basic trig, it's going to be hard to explain the translation terms. But, here's how you can figure it out yourself assuming you do understand basic geometry and trig:

- draw an x/y axis
- draw a rectangle on it somewhere, label the center of the rectangle x0,y0
- draw a rotated x/y axis, rotating about the 0,0 point, label the amount of rotation 'angle'
- examine where your rectangle is relative to the new axis
- by drawing the correct right triangles, you'll be able to figure out the new center point relative to the original center point x0,y0

....and I might have got it wrong

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•