I am trying to draw a rectangle with java awt and make it rotate with mouse cursor by mouse dragging.
When I was testing it out, the rectangle was rotating ridiculously fast.
My Rectangle():
private Rectangle2D rec = new Rectangle2D.Float(x0,y0,w,h);
AffineTransform recTrans = new AffineTransform();
int pivotX = x0+w/2, pivotY = y0+h;
// (0,0) is at the top-left corner
My paintComponent():
public void paintComponent(Graphics g) {
Graphics2D graph = (Graphics2D) g;
graph.translate(x,y);
graph.transform(recTrans);
graph.fill(rec);
graph.setColor(Color.blue);
graph.draw(rec);
}
My mouse dragging event:
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
previousX = e.getX();
previousY = e.getY();
}
});
addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
currentX = e.getX();
currentY = e.getY();
double angle1 = Math.atan2(currentY-pivotY, currentX-pivotX);
double angle2 = Math.atan2(previousY-pivotY, previousX-pivotX);
double theta = angle2 - angle1;
recTrans.rotate(theta, pivotX, pivotY);
}
});
So supposedly the scenario looks like:
But when I slightly drag(theta less than 10 degree) the rectangle to the right side, the rectangle rotates even to the bottom of the pivot point.
Another note, the rectangle rotates but the coordinates of the four corners of the rectangle yet have changed.
I am quite lost when doing those transformation tasks with java..
I think that the problem is that you are accumulating the rotation for each mouse motion event you get: when you move the mouse 10 degrees you don't get just one event at the end of the movement, you get a bunch of events all along the way. And it seems that you are accumulating the rotation of all of them in the same transformation, so when you get to 10 degrees, you have actually 1 + 2 + 3 + 4...
you get the idea.
The solution is easy: reset the transformation before applying the rotation:
recTrans.setToIdentity();
recTrans.rotate(theta, pivotX, pivotY);
Or equivalently but nicer, use this function that does not accumulate the transformation.
recTrans.setToRotation(theta, pivotX, pivotY);