简体   繁体   English

获取旋转矩形的角

[英]Get the corners of a rotating rectangle

I have a rectangle that rotates around it's middle and I have another rectangle that I want to connect to the upper right corner of the rotating rectangle. 我有一个围绕它的中间旋转的矩形,我有另一个矩形,我想连接到旋转矩形的右上角。 The problem is that I have no idea how to get the corner so that the second rectangle always will be stuck to that corner. 问题是我不知道如何到达角落,以便第二个矩形总是会粘在那个角落。

This is my sample code. 这是我的示例代码。 Right now the second rectangle will be at the same place all the time which is not the result that I'm after. 现在第二个矩形将始终在同一个地方,这不是我追求的结果。

package Test;

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;

class Test{

    public static void main(String[] args){
        new Test();
    }

    public Test(){
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new Graphic());
                frame.setSize(1000,700);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}

class Graphic extends JPanel{
    private int x, y, windowW, windowH;
    private double angle;
    private Rectangle rect1, rect2;
    private Path2D path;
    private Timer timer;
    private AffineTransform rotation;

    public Graphic(){
        windowW = (int) Toolkit.getDefaultToolkit().getScreenSize().getWidth();
        windowH = (int) Toolkit.getDefaultToolkit().getScreenSize().getHeight();
        path = new Path2D.Double();
        rotation = new AffineTransform();
        angle = 0;
        x = windowW / 2;
        y = windowH / 2;
        timer = new Timer(100, new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e){
                angle += .1;
                if(angle > 360) angle -= 360;
                repaint();
            }
        });
        timer.start();
    }

    @Override
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        rotation.setToTranslation(500, 200);
        rotation.rotate(angle, 32, 32);
        rect1 = new Rectangle(0, 0, 64, 64);
        path = new Path2D.Double(rect1, rotation);
        rect2 = new Rectangle(path.getBounds().x, path.getBounds().y, 10, 50);
        g2d.fill(path);
        g2d.fill(rect2);
    }
}

Mathematical solution :) 数学解决方案:)

public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D) g;
    rotation.setToTranslation(500, 200);
    rotation.rotate(angle, 32, 32);
    rect1 = new Rectangle(0, 0, 64, 64);
    path = new Path2D.Double(rect1, rotation);
    double r = 32.0 * Math.sqrt(2);
    // (532, 232) - coordinates of rectangle center        |
    // you can change position of second rectangle by this V substraction (all you need to know is that the full circle corresponds to 2Pi)
    int x2 = (int) Math.round(532 + r * Math.cos(angle - Math.PI / 4));
    int y2 = (int) Math.round(232 + r * Math.sin(angle - Math.PI / 4));
    rect2 = new Rectangle(x2, y2, 10, 50);
    g2d.fill(path);
    g2d.fill(rect2);
}

Of course, some constants should be class fields, not method variables. 当然,一些常量应该是类字段,而不是方法变量。

I can't test this code to be sure but I believe it is the proper working code that you want 我无法测试此代码,但我相信它是您想要的正确工作代码

int hw = -width / 2;
int hh = -height / 2;
int cos = Math.cos( theta );
int sin = Math.sin( theta );
int x = hw * cos - hh * sin;
int y = hw * sin + hh * cos;

This will get you the top left corner based on the theta, rotation, of the square. 这将根据方块的θ,旋转,左上角。 To get the other corners you just use change the hw and hh values: 要获得其他角落,您只需使用更改hw和hh值:

//top right corner
hw = width / 2
hh = -height / 2

//bottom right corner
hw = width / 2
hh = height / 2

//bottom left corer
hw = -width / 2
hh = height / 2

I hope this helps 我希望这有帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM