Java Programmer Java Programmer - 2 days ago 5
Java Question

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

Answer

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.

Comments