Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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);
    }
}
like image 726
Java Programmer Avatar asked May 27 '13 17:05

Java Programmer


People also ask

What do you get when you rotate a rectangle?

A rectangle can be rotated about its center and it will look exactly the same and be in the same location. The only difference is the location of the named points.

How do you find the coordinates of a rotating point?

Coordinates of Rotation: The point (x,y) rotated an angle of θ counter-clockwise about the origin will land at point (x′,y′) where x′=xcos(θ)−ysin(θ) x ′ = x cos ⁡ ( θ ) − y sin ⁡ and y′=ycos(θ)+xsin(θ) y ′ = y cos ⁡ ( θ ) + x sin ⁡ .


2 Answers

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.

like image 135
Patison Avatar answered Oct 24 '22 06:10

Patison


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:

//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

like image 42
Andrew Cumming Avatar answered Oct 24 '22 07:10

Andrew Cumming