在 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)
我正在制作一个 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)