0
votes

I am trying to rotate a Polygon around its own center point according to a given theta variable. It seems to work somewhat, but there are some big problems. It rotates, at an increasing speed which I do not understand. The Polygon itself also shrinks in size as it rotates until the points move into each other.

Here is the main rotating part of my code.

public void Rotate(double dTheta)
{
    this.theta += dTheta;

    for(int i = 0; i < body.npoints; i++)
    {
        body.xpoints[i] = 
                (int) (body.getBounds2D().getCenterX() + (body.xpoints[i] - body.getBounds2D().getCenterX()) * 
                        Math.cos(theta) - (body.ypoints[i] - body.getBounds2D().getCenterY()) * Math.sin(theta));

        body.ypoints[i] = 
                (int) (body.getBounds2D().getCenterY() + (body.xpoints[i] - body.getBounds2D().getCenterX()) * 
                        Math.sin(theta) + (body.ypoints[i] - body.getBounds2D().getCenterY()) * Math.cos(theta));
    }
}

The 'body' object is a Polygon that is drawn each frame at a rate of 60 FPS.

The theta variable increases by a factor of Math.PI / 180 when the user pressed the space key.

The rather large math operation I'm using was something I found on the web, it is supposed to rotate a point according to a radian angle and an anchor point.

The 'body' Polygon itself consists of the points (-16, 0), (16, -16), and (16, 16). The 'body' Polygon is initially placed at the location (100, 100) and does not translate from there aside from the rotation.

I would greatly appreciate any help on this subject, thank you in advance.

2
Are you using some framework like Slick2D or lwjgl? With Slick2D it's two simple linesSaulius Šimčikas
Actually I am creating my own game engine. The only external library I'm using is JNativeHook to handle mouse and keyboard input (It helps eliminate multi-os erros with keys and such). I do all my my drawing with the JPanel's paint method and a cast Graphics2D object.BigBerger

2 Answers

0
votes

Okay so I feel a bit incompetent asking for help so quickly when I have approached the problem from a bad angle.

I fixed my problem by storing the points of the original polygon in two int arrays named xpoints and ypoints. These points will never change once loaded, they do not relate to the position of the Polygon rather they relate to the position of the points around the Polygon's center which can change at any given moment.

What I did was looped through all of these points each frame, and used the AffineTransform class to get a rotated instance of each point using (0, 0) as the center. I then constructed a Polygon object out of these rotated points and translated it based on the player's x and y position (Which are stored variables in my class).

This is the segment of code that I use.

public void DoFrame(Graphics2D g)
{
    // Increment x by the dx factor
    x += dx * game.GetDeltaTime();
    // Increment y by the dy factor
    y += dy * game.GetDeltaTime();

    // Reset the body polygon
    body.reset();
    // Loop through all of the reference polygon points
    for(int i = 0; i < xpoints.length; i++)
    {
        // Create a placeholder array for the two points
        double[] pt = {xpoints[i], ypoints[i]};
        // Rotate the points around a center (0, 0)
        AffineTransform.getRotateInstance(theta, 0, 0).transform(pt, 0, pt, 0, 1);
        // Add the rotated point to the body
        body.addPoint((int) pt[0], (int) pt[1]);
    }
    // Translate the body based on x and y coordinates
    body.translate((int) x, (int) y);
}

This will roughly display a rotated polygon based on the center of the original passed points, note however that the center used is not a perfect center rather it depends upon the positioning of the points upon the call of the constructor.

0
votes

You are not applying the rotation transform the way you think. Because you first modify x and use the modified value to compute y. Save a copy of x.