batman
batman

Reputation: 90

Keep a square at the corner of a rotated square in Java

I'm making a zamboni driving game and im doing collision detection. I'm trying to make it by checking if a corner of the zamboni is inside a wall. I draw a rectangle at the corner location by using LWJGL. At the moment, I have the corner located at the center of the zamboni, but I want it to be at the top left corner of it. I can make this, but when I rotate the zamboni, the corner thing does not go to the location of the actual corner of the zamboni, but instead it stays at the same position as when the zamboni is not rotated.

Here's my code:

cornerLocation.x = position.x + (float) Math.cos(Math.toRadians(angle + 90));
cornerLocation.y = position.y + (float) Math.sin(Math.toRadians(angle + 90));

position is a vector where i store the location of the zamboni. The origin of it is at the center so the top-left corner of the zamboni is basically at position-size/2.

How can I make it so it is always at the actual corner the the zamboni, even when I rotate it?

Upvotes: 4

Views: 181

Answers (1)

David Pérez Cabrera
David Pérez Cabrera

Reputation: 5068

You need two set of coordinates:

  • Zamboni corners points.
  • Rectangle points for collision detection.

The Rectangle points can be calculated from zamboni corners. For this: You must to get the "min-x" and the "min-y" of them:

Point topLeftRect = new Point(Math.min(zamboniCorner1.x,zamboniCorner2.x,zamboniCorner3.x,zamboniCorner4.x),
                              Math.min(zamboniCorner1.y,zamboniCorner2.y,zamboniCorner3.y,zamboniCorner4.y));

Point bottomRightRect = new Point(Math.max(zamboniCorner1.x,zamboniCorner2.x,zamboniCorner3.x,zamboniCorner4.x),
                                  Math.max(zamboniCorner1.y,zamboniCorner2.y,zamboniCorner3.y,zamboniCorner4.y));

Rectangle collisionDetectionRectangle =new Rectangle(topLeftRect,bottomRightRect);

Detection collisions rectangle size is usually greater than the Zamboni Size.

What happens with rotation?

Steps (one of many possibles ways)

the 2d points {x,y} -> goes to 3d: {x, y, 1}

float[][] zamboniCorner1Point3d = {{zamboniCorner1.x,zamboniCorner1.y,1}};
...
float[][] zamboniCorner4Point3d = {{zamboniCorner4.x,zamboniCorner4.y,1}};

1.- You need to move zamboni's center to (0,0) and you drop the zamboni corners with center:

You can used this 3-d matrix (1):

float[][] translationMatrix1 = {{1, 0,-zamboniCenter.x},{0, 1,-zamboniCenter.y},{0, 0, 1}};

float[][] zamboniCorner1Point3dNew = Matrix.cross(zamboniCorner1Point3d,translationMatrix1);
...
float[][] zamboniCorner4Point3dNew = Matrix.cross(zamboniCorner4Point3d,translationMatrix1);

Point' -> Point * Matrix1

2.- You need to rotate all cordinates (center of zamboni doesn't change, it's {{0,0,1})

You can used this 3-d matrix (2):

float[][] rotationMatrix2 = {Math.cos(rotationAngle), Math.sin(rotationAngle), 0 }, {-Math.sin(rotationAngle), Math.cos(rotationAngle), 0}, {0, 0, 1 }};


float[][] zamboniCorner1Point3dNew = Matrix.cross(zamboniCorner1Point3dNew,rotationMatrix2);
...
float[][] zamboniCorner4Point3dNew = Matrix.cross(zamboniCorner4Point3dNew,rotationMatrix2);

Point' -> Point * Matrix2

3.- You need to move zamboni's center (from the {0,0,1}) to original position (in the same place at first {{zamboniCenter.x,zamboniCenter.y,1}}) and drop the corners with center.

You can used a 3-d matrix(3): 


float[][] translationMatrix3 = {{1, 0, zamboniCenter.x},{0, 1, zamboniCenter.y},{0, 0, 1}};

float[][] zamboniCorner1Point3dNew = Matrix.cross(zamboniCorner1Point3dNew,translationMatrix3);
...
float[][] zamboniCorner4Point3dNew = Matrix.cross(zamboniCorner1Point3dNew,translationMatrix3);

Point' -> Point * Matrix3

4.- Set the new values.

zamboniCorner1.x = zamboniCorner1Point3dNew[0];
zamboniCorner1.y = zamboniCorner1Point3dNew[1];
...
zamboniCorner4.x = zamboniCorner4Point3dNew[0];
zamboniCorner4.y = zamboniCorner4Point3dNew[1];

5.- Then, obtain: min-x, min-y, max-x and max-y of the new zamboni corners, there's your new collision detection rect. top-lef: (min-x,min-y) bottom-right:(max-x,max-y).

Point topLeftRect = new Point(Math.min(zamboniCorner1.x,zamboniCorner2.x,zamboniCorner3.x,zamboniCorner4.x),
                              Math.min(zamboniCorner1.y,zamboniCorner2.y,zamboniCorner3.y,zamboniCorner4.y));

Point bottomRightRect = new Point(Math.max(zamboniCorner1.x,zamboniCorner2.x,zamboniCorner3.x,zamboniCorner4.x),
                                  Math.max(zamboniCorner1.y,zamboniCorner2.y,zamboniCorner3.y,zamboniCorner4.y));

Rectangle collisionDetectionRectangle =new Rectangle(topLeftRect,bottomRightRect);

The steps 1, 2 and 3; can be computed together:

float[][] matrix = Matrix.cross(Matrix.cross(translationMatrix1,rotationMatrix2),translationMatrix3);

float[][] zamboniCorner1Point3dNew = Matrix.cross(zamboniCorner1Point3d,matrix);
...
float[][] zamboniCorner4Point3dNew = Matrix.cross(zamboniCorner4Point3d,matrix);


Point' -> Point * (Matrix-1 * Matrix-2 * Matrix-3)

Upvotes: 1

Related Questions