首先,让我们弄清楚如何表示圆形和正方形。
在约定中,square
表示如下:
squarexX, squareY + height ------------ squareX+ width, squareY +height
| |
| |
squareX, squareY ------------- squareX + width, squareY
Whilecircle
由圆的坐标(circleX, circleY)
和radius
值表示。考虑到这一点,您甚至应该能够编写自己的函数。请注意,圆没有宽度或高度。
所以在他们的代码中:
if(circleX < squareX) distance += pow(circleX - boxX,2); //x-axis
应该
if(circleX < squareX) distance += pow(circleX - squareX,2); //x-axis
判断正方形是否与圆形重叠/碰撞的思路如下:
- 假设正方形位于二维平面的原点,如果不是,我们可以将原点移动到正方形的中心
- 接下来,找出圆与正方形最近的边缘交点之间的距离,如果这个距离大于半径,则不重叠,否则重叠。一个特殊的情况是,如果圆位于正方形内部,那么所谓的交点就是圆本身的中心。在这种情况下,testForCollision 将返回 true。
完整的函数应该如下所示:
//this function computes the distance between center of circle
//to closest point on one of the edges of square, that edge is on the
//same side as the circle
#include <algorithm>
bool testForCollision(int circleX, int circleY, int width, int height, int radius)
{
int dx = std::min(circleX, (int)(width * 0.5));
int dx1 = std::max(dx, (int)(-width *0.5));
int dy = std::min(circleY, (int)(height * 0.5));
int dy1 = std::max(dy, (int)(-height * 0.5));
return (dx1 - circleX) * (dx1 - circleX)
+ (dy1 - circleY) * (dy1 - circleY) <= radius * radius;
}
bool Collision(int circleX, int circleY, int radius,
int squareX, int squareY, int width, int height)
{
//get center of square
int center_of_square_x = squareX + width/2;
int center_of_square_y = squareY + height/2;
//if square is already at origin, test directly
if ( center_of_square_x == 0 && center_of_square_y ==0)
{
return testForCollision(circleX, circleY, width, height, radius);
}
else
{
//shift center of square to origin and update coordinates of circle
//only consider part of the situation, more to add about shifting
circleX = circleX - center_of_square_x;
circleY = circleY - center_of_square_y;
return testForCollision(circleX, circleY, width, height, radius);
}
}
这样,它应该能够识别圆形和正方形是否相互碰撞。
编辑:让我们通过一个测试用例:
circleX = 60 circleY = 172 radius = 39
squareX = 120 squareY = 180 width = 72 height = 72
我们有正方形的坐标如下(包括中心)
120, 252 -------- 192, 252
| |
|--------156,216----|
| |
120,180 ---------192,180
我们可以看到 (60,172) 位于边缘 (120,252)-->(120,180) 的左侧,(120,180) 和 (60,72) 之间的距离大于 39。 (120,252) 和 (60,72) 之间的距离也大于39,没有重叠。为了更好地理解它,给定圆心 (60,172) 和半径 39,您可以从圆心到达的 x 和 y 范围是 (60-39,60 +39) = (21,99) 和 ( 172-39, 172+39) = (133,211)。如果您将其可视化,这应该与正方形没有重叠。
如果您首先将原点转换为 (156,216),我们将 (-96,-44) 作为新坐标系中的圆心。它位于第三象限。如果您运行 testForCollision 函数,您将看到没有重叠。
dx = min(-96,36) = -96
dx1 = max(dx, -36) = -36
dy = min(-44, 36) = -44
dy1 = max(dy,-36) = -36
distance = (-36 - (-96))^2 + (-36 - (-44))^2 = 60^2 + 8^2 > 39^2, so no overlap