0

I'm working on a game where you are a spaceship. This spaceship has to be able to rotate. The rectangle has two arrays x[], y[] containing all the corners positions of the rectangle. But when I apply the rotation formula, I get a rather wierd rotation. To try to explain it, it looks like it's rotating the bottom left of the screen.

To make these corner arrays i take in an x position, y position, width and height.

Making of the corner-arrays

public Vertex2f(float x, float y, float w, float h){
    this.x[0] = x; 
    this.y[0] = y;

    this.x[1] = x+w;
    this.y[1] = y;

    this.x[2] = x+w;
    this.y[2] = y+h;

    this.x[3] = x;
    this.y[3] = y+h;
}

My rotation function

public void rotate(float angle){
    this.rotation = angle;

    double cos = Math.cos(rotation);
    double sin = Math.sin(rotation);

    for(int i = 0; i < x.length; i++){
        x[i] = (float)(cos * x[i] - sin * y[i]);
        y[i] = (float)(sin * x[i] + cos * y[i]);

    }

}

If it helps I am using LWJGL/OpenGL in java for all the graphics and Slick2d to load and init the sprites I am using.

Devtons
  • 15
  • 8

2 Answers2

0

Try this one:

public void rotate(float angle){
    this.rotation = angle;

    double cos = Math.cos(rotation);
    double sin = Math.sin(rotation);

    double xOffset = (x[0]+x[2])/2;
    double yOffset = (y[0]+y[2])/2;

    for(int i = 0; i < 3; i++){
        x[i] = (float)(cos * (x[i]-xOffset) - sin * (y[i]-yOffset)) + xOffset;
        y[i] = (float)(sin * (x[i]-xOffset) + cos * (y[i]-yOffset)) + yOffset;

    }

}

you have to rotate around center of your rectangle. Otherwise center is in x=0 and y=0

edited:

public void rotate(float angle){
    this.rotation = angle;

    double cos = Math.cos(rotation);
    double sin = Math.sin(rotation);

    double xOffset = (x[0]+x[2])/2;
    double yOffset = (y[0]+y[2])/2;

    for(int i = 0; i < 3; i++){
        double newX = (float)(cos * (x[i]-xOffset) - sin * (y[i]-yOffset)) + xOffset;
        double newY = (float)(sin * (x[i]-xOffset) + cos * (y[i]-yOffset)) + yOffset;

        x[i] = newX;
        y[i] = newY;
    }
}

see other thread

Community
  • 1
  • 1
Nikita
  • 163
  • 2
  • 9
0

The problem with the formulas

    x[i] = (float)(cos * x[i] - sin * y[i]);
    y[i] = (float)(sin * x[i] + cos * y[i]);

apart from the missing rotation center is that you change x[i] in the first formula but expect to use the original value in the second formula. Thus you need to use local variables lx, ly as in

    float lx = x[i] - xcenter;
    float ly = y[i] - ycenter;
    x[i] = xcenter + (float)(cos * lx - sin * ly);
    y[i] = ycenter + (float)(sin * lx + cos * ly);

If the object already is rotated with an angle of rotation, then this code adds the angle angle to the total rotation angle. If instead the given argument angle is to be the new total rotation angle, then the sin and cos values need to be computed with the angle difference. That is, start the procedure with, for instance,

public void rotate(float angle){


    double cos = Math.cos(angle - rotation);
    double sin = Math.sin(angle - rotation);

    this.rotation = angle;
Lutz Lehmann
  • 25,219
  • 2
  • 22
  • 51
  • It looks as though the ship is just rotating/scaling and flipping on the x axis – Devtons May 04 '15 at 20:22
  • This code, as the original per intention, adds the angle that is given as argument to the existing rotation. The scale should remain the same, there should be no (mirror) flips. If you want to make the given angle the new absolute angle, then set `angle = angle - rotation; rotation = rotation + angle; sin=Math.sin(angle); cos=Math.cos(angle)`. Or keep local and global coordinates separate. – Lutz Lehmann May 04 '15 at 20:58