How would one go about rotating the mouse coordinate system when a rotation is applied to a Canvas? When I rotate the Canvas, the mouse stays in the same position relative to the rotated components. I would like to have the mouse coordinates consider the rotation of the component, instead of the coordinates being the position relative to the window, with no consideration for rotation.
I've provided a picture to illustrate more of what I'm getting at. The black box represents a shape for reference, and the purple box lies on the mouse coordinates. Rotation example image
Leftmost picture - Unrotated Canvas Middle picture - Rotated Canvas as Java sees it Rightmost picture - Desired outcome
My example code simulates a Canvas that rotates by pressing the left or right arrow keys. This simulation shows how the mouse stays in a position relative to rotated components, rather than relative to my mouse on screen.
Is there a way to transform or calculate these new coordinates (shown in the rightmost image) so that they lock onto my mouse in the window, regardless of rotation?
package rotation;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
@SuppressWarnings("serial")
public class RotationExample extends Canvas implements Runnable{
boolean isRunning = false;
boolean left = false;
boolean right = false;
AffineTransform transform = new AffineTransform();
double rotation = 0.0d;
public RotationExample() {
//Create jframe
JFrame f = new JFrame();
f.setSize(500, 500);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setResizable(false);
f.setUndecorated(true);
//Add key listener
this.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
int k = e.getKeyCode();
//Set left and right variables
if(k == KeyEvent.VK_LEFT) left = true;
if(k == KeyEvent.VK_RIGHT) right = true;
}
public void keyReleased(KeyEvent e) {
int k = e.getKeyCode();
if(k == KeyEvent.VK_LEFT) left = false;
if(k == KeyEvent.VK_RIGHT) right = false;
}
});
f.add(this);
f.setVisible(true);
start();
}
public void render() {
BufferStrategy bs = this.getBufferStrategy();
if(bs == null){
this.createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
Graphics2D gt = (Graphics2D) g;
gt.setTransform(transform);
gt.clearRect(0, 0, 500, 500);
//Increment rotation based on left or right variables
if(left) rotation += 0.001;
else if(right) rotation -= 0.001;
//Rotate around middle of frame
gt.rotate(rotation, 250, 250);
//Draw black rectangle in middle
gt.setColor(Color.BLACK);
gt.fillRect(175, 175, 150, 150);
//Draw red up arrow
gt.setColor(Color.RED);
gt.fillPolygon(new int[] {250, 300, 270, 270, 230, 230, 200}, new int[] {200, 250, 250, 300, 300, 250, 250}, 7);
//Draw rectangle at mouse coordinates
gt.setColor(Color.MAGENTA);
Point m = MouseInfo.getPointerInfo().getLocation();
gt.fillRect((int) m.getX() - 8, (int) m.getY() - 8, 16, 16);
bs.show();
gt.dispose();
}
public static void main(String[] args) {
new RotationExample();
}
public void start() {
isRunning = true;
new Thread(this).start();
}
public void run() {
//Continuous rendering
while(isRunning) {
render();
}
}
}
java.awt.Robot
? Calculating the new position of the purple square is a simple geometric coordinate transform, then move the mouse to the new coordinates. The coordinate transform is a pure geometry question unrelated to programming, and reference info is available lots of places on the web. – Jim Garrison