将矩形多边形沿其中心旋转(Java)

4

我有一个绘制矩形的代码(多边形对象),然后使用旋转矩阵绘制另一个矩形,该矩形是原始矩形旋转90度后的结果。

public class DrawingPanel extends JPanel{

    public void paintComponent(Graphics g){

        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;

        Point p1,p2,p3,p4;
        p1 = new Point(50,50);
        p2 = new Point(200,50);
        p3 = new Point(200,100);
        p4 = new Point(50,100);

        int[] x = {(int) p1.getX(), (int) p2.getX(), (int)p3.getX(), (int) p4.getX()};
        int[] y = {(int) p1.getY(), (int) p2.getY(), (int)p3.getY(), (int) p4.getY()};

        Polygon poly = new Polygon(x, y, x.length);
        g2d.draw(poly);

        p1.setLocation(p1.getX() * Math.cos(Math.toRadians(90)) - p1.getY() * Math.sin(Math.toRadians(90)),
                p1.getX() * Math.sin(Math.toRadians(90)) + p1.getY() * Math.cos(Math.toRadians(90)));
        p2.setLocation(p2.getX() * Math.cos(Math.toRadians(90)) - p2.getY() * Math.sin(Math.toRadians(90)),
                p2.getX() * Math.sin(Math.toRadians(90)) + p2.getY() * Math.cos(Math.toRadians(90)));
        p3.setLocation(p3.getX() * Math.cos(Math.toRadians(90)) - p3.getY() * Math.sin(Math.toRadians(90)),
                p3.getX() * Math.sin(Math.toRadians(90)) + p3.getY() * Math.cos(Math.toRadians(90)));
        p4.setLocation(p4.getX() * Math.cos(Math.toRadians(90)) - p4.getY() * Math.sin(Math.toRadians(90)),
                p4.getX() * Math.sin(Math.toRadians(90)) + p4.getY() * Math.cos(Math.toRadians(90)));

        int[] x2 = {(int) p1.getX(), (int) p2.getX(), (int)p3.getX(), (int) p4.getX()};
        int[] y2 = {(int) p1.getY(), (int) p2.getY(), (int)p3.getY(), (int) p4.getY()};

        Polygon poly2 = new Polygon(x2, y2, x2.length);
        g2d.draw(poly2);

    }

}

目前,第二个矩形没有显示出来。在另一个问题中,有人回答说这是因为它绘制在屏幕外。

我问如何使矩形围绕其中心旋转,以便新的绘图将出现在屏幕上,他回答了,但我不太明白如何在代码中实现他所说的内容(尝试了一些不起作用的东西)。

您能否在代码中准确地向我展示如何使矩形围绕其中心旋转?

(当然,这不是实际对象的旋转。它是制作一个旋转后的副本对象)。

希望能得到帮助。谢谢


为什么不将图形转换为矩形中心,然后进行旋转,接着使用这些新坐标绘制一个矩形(再对图形进行反旋转和反平移)? - JB Nizet
2个回答

17

由于您想要围绕矩形的中心旋转,首先需要将矩形平移到原点,然后进行旋转,最后再平移回去。请参考以下代码(根据您的情况进行调整)来自此答案的另一篇帖子。

//TRANSLATE TO ORIGIN
double x1 = p1.getX() - center.x;
double y1 = p1.getY() - center.y;

//APPLY ROTATION
double temp_x1 = x1 * Math.cos(angle) - y1 * Math.sin(angle));
double temp_y1 = x1 * Math.sin(angle) + y1 * Math.cos(angle));

//TRANSLATE BACK
p1.setLocation(temp_x1 + center.x, temp_y1 + center.y);

你需要对每个点进行这个操作。此外,你需要找到矩形的中心 center.xcenter.y

说明 当你直接应用旋转时,你会将它围绕原点 (0,0) 旋转(当你在代码中改变旋转角度时,你很容易看到这一点)。如果你想围绕矩形的中心旋转,你必须按照上面描述的步骤进行。

  • 将形状(矩形)平移到原点,这可以通过从点的分量中减去中心分量来完成。
  • 围绕原点 (0,0) 对翻译后的点进行旋转
  • 将每个点重新平移到原始位置,通过添加中心分量(在第一步中减去的分量)。

编辑1:

假设我们有一个正方形,其顶点为:

p1: (2, 2)
p2: (3, 2)
p3: (3, 3)
p4: (2, 3)

对于点p2

第一步:

center: (2.5, 2.5)
x1 = 3 - 2.5 = 0.5
y1 = 2 - 2.5 = -0.5

对于每个点执行以下操作:

new_p1: (-0.5, -0.5)
new_p2: (0.5, -0.5)
new_p3: (0.5, 0.5)
new_p4: (-0.5, 0.5)

然后您应用旋转...

编辑2:我希望这张图能让事情更清晰,如果我在绘画方面做得不好,请原谅。

Explanation


谢谢。一般来说,当人们提到“origin”时,他们是否总是指的是0,0? - user3150201
这是相对的,但一般来说是的。这解决了你遇到的问题吗? - Christian Tapia
那么在这种情况下,原点是整个窗口的0,0,还是矩形的左上角? - user3150201
抱歉我反应有点慢,但你能解释一下你建议的逻辑吗?旋转是如何工作的?为什么需要先平移到原点,然后旋转再平移回去?我想彻底理解这个过程。 - user3150201
1
好的,我现在明白了 :) 我混淆了中心点的x和y坐标以及矩形宽度/2和高度/2。感谢你的帮助和努力。真的非常感激 :) 干杯 - user3150201
显示剩余14条评论

1
旋转总是围绕0,0发生。
为了围绕对象中心旋转,需要移动点使对象中心位于0,0; 然后旋转它们; 然后再将它们移回原来的位置:
因此,如果cx和cy是您的中心:
    p1.setLocation((p1.getX()-cx) * Math.cos(Math.toRadians(90)) - (p1.getY()-cy) * Math.sin(Math.toRadians(90))+cx,
            (p1.getX()-cx) * Math.sin(Math.toRadians(90)) + (p1.getY()-cy) * Math.cos(Math.toRadians(90))+cy);

并且对于其他点也做同样的事情。

你所说的0,0是指整个窗口的0,0,还是矩形的左上角? - user3150201
我的意思是坐标空间。无论你需要做什么来将中心移动到0 0。 - Tim B

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