在Java的旋转方块的角落保持一个正方形

时间:2015-07-05 11:37:47

标签: java collision-detection

我正在制作zamboni驾驶游戏,我正在进行碰撞检测。我试图通过检查zamboni的一角是否在墙内来实现。我使用LWJGL在角落位置绘制一个矩形。此刻,我的角落位于赞博尼的中心,但我希望它位于它的左上角。我可以做到这一点,但是当我旋转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的左上角基本上处于位置大小/ 2处。

我怎么能这样做,所以它总是在zamboni的实际角落,即使我旋转它?

1 个答案:

答案 0 :(得分:1)

您需要两组坐标:

  • 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维矩阵(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,这是你的新碰撞检测矩形。     top-lef:(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);

步骤1,2和3;可以一起计算:

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)