Java GUI旋转和Rectangle的翻译

我试图在JPanel中绘制一个矩形,它可以平移,然后自行旋转以模仿汽车的运动。 我已经能够使矩形平移和旋转,但它围绕(0,0)的原点旋转。 我非常高兴我可以让矩形移动和旋转,因为我对Java GUI很新,但我似乎无法得到如何让矩形围绕它自己旋转,因为我尝试了更多它,当我初始化矩形并将其旋转45度,它的位置已更改,我假设是从旋转方法附加的变换矩阵。

我通过网站查看了如何解决这个问题,但是我只发现了如何旋转矩形而不是如何旋转和移动模拟汽车的运动。 我认为它关注它的变换矩阵,但我只是猜测。 所以我的问题是如何让矩形能够旋转并在自身周围移动而不是JPanel中的一个点。

这是我到目前为止的代码:

public class Draw extends JPanel implements ActionListener { private int x = 100; private int y = 100; private double theta = Math.PI; Rectangle rec = new Rectangle(x,y,25,25); Timer timer = new Timer(25,this); Draw(){ setBackground(Color.black); timer.start(); } public void paintComponent(Graphics g){ super.paintComponent(g); Graphics2D g2d = (Graphics2D)g; g2d.setColor(Color.white); rec.x = 100; rec.y = 100; g2d.rotate(theta); g2d.draw(rec); g2d.fill(rec); } public void actionPerformed(ActionEvent e) { x = (int) (x + (Math.cos(theta))*1); y = (int) (y + (Math.sin(theta))*1); theta = theta - (5*Math.PI/180); repaint(); } 

通常使用两种方法之一:

  • 围绕Shape的中心( xy )旋转图形上下文,如此处所示。

     rotate(double theta, double x, double y) 
  • 转换为原点,旋转并平移,如此处所示。

     g2d.translate(this.getWidth() / 2, this.getHeight() / 2); g2d.rotate(theta); g2d.translate(-image.getWidth(null) / 2, -image.getHeight(null) / 2); 

请注意第二个示例中连接的明显相反顺序。

附录:仔细观察您的示例,以下更改会围绕面板中心旋转Rectangle

 g2d.rotate(theta, getWidth() / 2, getHeight() / 2); 

此外,使用@Override注释,并为您的面板提供合理的首选大小:

 @Override public Dimension getPreferredSize() { return new Dimension(640, 480); } 

使用仿射变换旋转矩形并将其转换为旋转多项式。 检查以下代码:

 public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; g2d.setColor(Color.white); /* rotate rectnagle around rec.x and rec.y */ AffineTransform at = AffineTransform.getRotateInstance(theta, rec.x, rec.y); /* create the plunomial */ Polygon p = new Polygon(); /* path interator of the affine transformed polynomial */ PathIterator i = rec.getPathIterator(at); while (!i.isDone()) { double[] points = new double[2]; i.currentSegment(points); p.addPoint((int) points[0], (int) points[1]); i.next(); } g2d.fill(p); }