1

I'm doing a couple of tests with polygons (rotating them) and I've run into an annoying issue that crops up while I'm rotating them. The issue is, the polygons seem to be moving when they rotate, and eventually they fly out of the screen. I've been using AffineTransform to rotate them, and I haven't been translating them so they shouldn't be moving, right? Here's the code:

import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;

public class PhysicsProp {
    Point2D[] OriginalPoints;
    Point2D[] NewPoints = OriginalPoints;

    int X;
    int Y;

    double rotation = 0.0;

    public PhysicsProp(Point2D[] Points){
        OriginalPoints = Points;
        NewPoints = Points;
    }

    public Polygon PointsToPoly(Point2D[] Points){
        Polygon p = new Polygon();
        for (int i = 0; i < Points.length; i++){
            p.addPoint((int) Points[i].getX(), (int) Points[i].getY());
        }
        return p;
    }

    public void rotateModel(double theta){
        AffineTransform.getRotateInstance(Math.toDegrees(theta), PointsToPoly(NewPoints).getBounds().getCenterX(), PointsToPoly(NewPoints).getBounds().getCenterY()).transform(OriginalPoints, 0, NewPoints, 0, OriginalPoints.length);
    }

    public Polygon getModel(){
        return PointsToPoly(NewPoints);
    }

    public void setModel(Point[] points){
        OriginalPoints = points;
    }

    public Rectangle getBounds(){
        return PointsToPoly(NewPoints).getBounds();
    }
}

I'd like to know what's actually going wrong with this code, and if there's a better way around what I'm trying to achieve (rotating polygons). Here's where I render and rotate the polygons:

g2.setColor(Color.pink);
            for (PhysicsProp p : CurrentLevel.PhysicsObjects){
                g2.drawPolygon(p.PointsToPoly(p.NewPoints));
                p.rotateModel(0.001);
            }

Thanks for any help!

cstream24
  • 25
  • 7
  • 1
    What is the centerpoint of the polygon? – Tony Ennis Aug 15 '13 at 23:29
  • 1
    Try caching the centerpoint of the polygon, and always using that cached point as the point around which to rotate. Nothing guarantees that you'll calculate the same exact X/Y center point for any arbitrary polygon in any arbitrary rotation, so remove the risk (and the CPU cycles) and cache it once and just reuse from there. – Tim Aug 15 '13 at 23:36
  • 1
    +1 @Tim (who should post that as an answer). If you're constantly rotating then recalculating the centroid, rounding/precision errors will cause the centroid to drift. Alternatively just store a current transformation, and incrementally update the transformation each time you rotate, then you can apply the fully updated transformation to the original model instead of modifying the model one step at a time. – Jason C Aug 15 '13 at 23:38
  • See also this related [example](http://stackoverflow.com/a/5594424/230513). – trashgod Aug 15 '13 at 23:55
  • @andy256 - what exactly do you mean by this? Please explain. – cstream24 Aug 16 '13 at 00:17
  • Please ignore, I misread your code. – andy256 Aug 16 '13 at 01:35
  • +1 @JasonC: The suggestion to cache the entire transformation instead of just the center point is a great one; I didn't even consider that option. – Tim Aug 16 '13 at 14:15

1 Answers1

4

Try caching the centerpoint of the polygon, and always using that cached point as the point around which to rotate. Nothing guarantees that you'll calculate the same exact X/Y center point for any arbitrary polygon in any arbitrary rotation, so remove the risk (and the CPU cycles) and cache it once and just reuse from there.

Tim
  • 2,027
  • 15
  • 24
  • The centrepoint would have to be relative to the location of the polygon? – cstream24 Aug 16 '13 at 00:16
  • I just tried it, thank you very much for your help! I'd upvote if I could. – cstream24 Aug 16 '13 at 00:23
  • Glad it helped! As the OP, you can accept the answer even if you can't yet upvote it. But @Jason C's suggestion of caching the transformation instead of caching the center point is even better than mine from a performance standpoint, so I'd suggest you try it that way as well. – Tim Aug 16 '13 at 14:12