Java GUI 中矩形的旋转和平移

4
我正在尝试在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();
}

3
将矩形居中到(0,0)位置,进行旋转,然后再移回原来的位置。 - ApproachingDarknessFish
2个回答

7

通常有两种方法:

  • Rotate the graphics context around the center (x, y) of the Shape, as shown here.

    rotate(double theta, double x, double y)
    
  • Translate to the origin, rotate and translate back, as shown here.

    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);
}

1
谢谢你的答复,你提到的第一种方法正是我需要的。我没有意识到旋转方法有参数可以定位其坐标,所以我将矩形的位置作为参数放入了方法中,现在它运行得很好。再次感谢。 - John Cava
1
+1 非常好。@user1914793 还可以看看这个示例,其中使用了 AffineTransform#rotate(..)AffineTransform#createTransformedShape(): - David Kroukamp

1
使用仿射变换将矩形旋转并转换为旋转的多项式。请查看下面的代码:
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);
}

不需要迭代Shape的路径;可以使用createTransformedShape(),如此处所示。 - trashgod

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接