在 Java 的旋转正方形的角上保留一个正方形

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

我正在制作一个 zamboni 驾驶游戏,我正在做碰撞检测。我试图通过检查 zamboni 的一角是否在墙内来实现。我使用 LWJGL 在角落位置绘制了一个矩形。目前,我的角位于 zamboni 的中心,但我希望它位于左上角。我可以做到这一点,但是当我旋转 zamboni 时,角的东西不会转到 zamboni 的实际角的位置,而是保持在与 zamboni 不旋转时相同的位置。

这是我的代码:

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

position 是一个向量,我在其中存储 zamboni 的位置。它的原点在中心,所以 zamboni 的左上角基本上在 position-size/2.

我怎样才能让它始终位于 zamboni 的实际角落,即使我旋转它也是如此?

您需要两组坐标:

  • 赞博尼角球点数。
  • 用于碰撞检测的矩形点。

可以从 zamboni 角计算矩形点。为了这: 您必须获得其中的 "min-x" 和 "min-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);

检测碰撞矩形尺寸通常大于Zamboni尺寸。

旋转会发生什么?

步骤(许多可能的方法之一)

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.- 您需要将 zamboni 的中心移动到 (0,0) 并放下中心的 zamboni 角:

你可以使用这个 3-d 矩阵 (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.- 您需要旋转所有坐标(zamboni 的中心不变,它是 {{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.- 你需要将 zamboni 的中心(从 {0,0,1})移动到原来的位置(在同一个地方开始 {{zamboniCenter.x,zamboniCenter.y,1 }}) 并以中心放置角。

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.- 设置新值。

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

5.- 然后,获取:新的 zamboni 角的 min-x、min-y、max-x 和 max-y,这就是你的新碰撞检测矩形。 左上角:(min-x,min-y) 右下角:(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);

步骤一、二、三;可以一起计算:

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)