Search code examples
javarotationpoints

Polygon shape shrinks when it rotates


I am struggeling with the rotation of 6 points. These points rotate around a center point in the middle. But what happens is that the shapes area shrinks, and gets smaller and smaller.

The Drawing of the shape takes place on i JPanel with PaintComponent. This means that the canvas only supports integers positioning altough I can store positions in Doubles.

I use Point2D.Double for storing the points position I Rotate all the points by 1 deegre at each function call

I think my understanding of the rotation is lacking, I can rotate 360 deegre in one call, or 180, this works fine. But 45 deegres or 90 will completely turn my points into a line(picture below).

This problem has been bothering me for a while now, but as always, I am sure there is a simple solution.

Here is the rotation Function

@Override
public synchronized void rotatePoints(int move_x, int move_y) {
    // TODO Auto-generated method stub
    super.rotatePoints(move_x, move_y);

    BottomPanel.appendText("Area of Polygon is: " + UtilClass.calculateAreaOfPolygon(points)+ "\n");

    double degrees=1.0;
    double radians = degrees * (double)(Math.PI / 180.0);

    //GET THE CENTER POINT C
    Point2D.Double center = UtilClass.getCenterOfPolygon(points);

    //ITERATE THROUGH THE POINTS
    Iterator<PointClass> itr = points.iterator();

    while(itr.hasNext()) {

        //GET THE POINT
        PointClass point_class = itr.next();
        //point_class = points.get(3);

        //FIRST TRANSLATE THE DIFFERENCE
        double x1 = point_class.point.x - center.x;
        double y1 = point_class.point.y - center.y;

        //APPLY ROTATION MATRIX
        x1 = (x1 * Math.cos(radians)) - (y1 * Math.sin(radians));
        y1 = (x1 * Math.sin(radians)) + (y1 * Math.cos(radians));

        //TRANSLATE BACK
        point_class.point.setLocation(x1 + center.x, y1 + center.y);

        //ADD THE DEEGRES TO POINT CLASS
        point_class.angle += Math.toDegrees(radians);
    }
}

Here is the code for retriving a center location of a given polygon

public synchronized static Point2D.Double getCenterOfPolygon(List<PointClass> points) {

    //GETTING THE CENTER OF A COMPLEX POLYGON

    double combined_x = 0;
    double combined_y = 0;

    Iterator<PointClass> itr = points.iterator();

    while(itr.hasNext()) {

        PointClass point_class = itr.next();

        //ADD TO THE
        combined_x += point_class.point.x;
        combined_y += point_class.point.y;
    }

    double center_x = combined_x / (double)points.size();
    double center_y = combined_y / (double)points.size();

    return new Point2D.Double(center_x, center_y);
}

Here is a picture of the shape rotating all its points by 1 deegre clockwise

Shape

After each rotation I output the area of the polygon here is the result

  • Area of Polygon is: 6290
  • Area of Polygon is: 6288
  • Area of Polygon is: 6286
  • Area of Polygon is: 6284
  • Area of Polygon is: 6283
  • Area of Polygon is: 6281

Here is a picture of the shape rotating all its points by 90 deegre clockwise after one call. It clearely does not want to do that.

I would be glad for any suggestions or tips.

Shape


Solution

  • The error lies here:

    //APPLY ROTATION MATRIX
    x1 = (x1 * Math.cos(radians)) - (y1 * Math.sin(radians));
    y1 = (x1 * Math.sin(radians)) + (y1 * Math.cos(radians));
    

    x1 is being updated too early, such that y1 is calculated based on the new value of x1 instead of the old value.

    You could change it to something like this:

    //APPLY ROTATION MATRIX
    double temp;
    temp = (x1 * Math.cos(radians)) - (y1 * Math.sin(radians));
    y1   = (x1 * Math.sin(radians)) + (y1 * Math.cos(radians));
    x1   = temp;