Thursday, 9 January 2014

Rotating Points and/or Polygons around a center Point

After searching for what seems like hours to find a simple solution to this problem...and yes I know that AffineTransform can do this, but I knew there was a lot simpler/faster solution and one that doesn’t require creating new Objects.
The trick is to cache the angle and distance of each point from the center point. After doing so, the points can be rotated and the center point can be moved.
Here is the code...the angles are adjusted to 360 degrees...due north is zero.
import java.awt.*;
import javax.swing.*;

public class PointRotation extends JPanel
{
private Point points[] = new Point[4];
private double angles[] = new double[4];
private double distances[] = new double[4];
private Point center = new Point();
private float angle = 0;

public PointRotation()
{
setLayout(null);

int size = 20;
center.setLocation(100, 100);

points[0] = new Point(center.x - size, center.y - size);
points[1] = new Point(center.x + size, center.y - size);
points[2] = new Point(center.x + size, center.y + size);
points[3] = new Point(center.x - size, center.y + size);

angles[0] = this.getAngle360(center.x, center.y, points[0].x, points[0].y);
angles[1] = this.getAngle360(center.x, center.y, points[1].x, points[1].y);
angles[2] = this.getAngle360(center.x, center.y, points[2].x, points[2].y);
angles[3] = this.getAngle360(center.x, center.y, points[3].x, points[3].y);

distances[0] = center.distance(points[0]);
distances[1] = center.distance(points[1]);
distances[2] = center.distance(points[2]);
distances[3] = center.distance(points[3]);
}

protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;

g2.setPaint(Color.red);
g2.drawLine(points[0].x, points[0].y, points[1].x, points[1].y);
g2.setPaint(Color.blue);
g2.drawLine(points[1].x, points[1].y, points[2].x, points[2].y);
g2.setPaint(Color.green);
g2.drawLine(points[2].x, points[2].y, points[3].x, points[3].y);
g2.setPaint(Color.cyan);
g2.drawLine(points[3].x, points[3].y, points[0].x, points[0].y);

angle ++;
if (angle >= 360)
{
angle = 0;
}

for (int index = 0; index < points.length; index ++)
{
this.rotatePoint(index, angle);
}

try
{
Thread.sleep(20);
}
catch (Exception exception)
{
// Ignore
}

repaint();
}

private double getAngle360(double x1, double y1, double x2, double y2)
{
double angle = Math.toDegrees(Math.atan2(y2 - y1, x2 - x1));
if (angle < 0) angle = 180 + (180 - -angle);
angle += 90;
if (angle >= 360) angle -= 360;
return angle;
}

private void rotatePoint(int index, float angle)
{
double newAngle = angles


    + angle;
    if (newAngle >= 360) newAngle -= 360;

    double radians = Math.toRadians(newAngle);
    double distance = this.distances

      ;
      int deltaX = (int) (distance * Math.sin(radians));
      int deltaY = (int) (distance * -Math.cos(radians));

      points

        .setLocation(center.x + deltaX, center.y + deltaY);
        }

        public static void main(String[] args)
        {
        PointRotation c = new PointRotation();
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.getContentPane().add(c);
        f.setSize(400, 450);
        f.setLocation(0, 325);
        f.setVisible(true);
        }
        }

        No comments: