我只是想“检查”如果两个不同的几何形状对象发生碰撞。一个是圆形,第二个是正方形。我搜索谷歌找到一个简单的例子并从中学习,因为我不知道该怎么做。我找到了这个例子,尝试过,但没有发生任何事情。代码中存在大多数错误。请帮我用C或C ++语言纠正它。
bool Collision(int circleX, int circleY, int radius, int squareX, int squareY, int width, int height)
{
int distance = 0;
if(circleX < squareX)
distance += pow(circleX - boxX,2); //x-axis
else if (circleX > squareX + width)
distance += pow(circleX - squareX - width, 2);
if(circleY < squareY)
distance += pow(circleY - squareY,2); //y-axis
else if (circleY > squareY + height)
distance += pow(circleY - squareY - height, 2);
if( distance <= pow(radius, 2))
return true;
else
return false;
}
答案 0 :(得分:3)
首先,让我们清楚如何表示一个圆圈和一个正方形。
按惯例,square
表示如下:
squarexX, squareY + height ------------ squareX+ width, squareY +height
| |
| |
squareX, squareY ------------- squareX + width, squareY
circle
由圆圈(circleX, circleY)
和radius
的坐标表示。考虑到这一点,您甚至可以编写自己的功能。请注意,圆圈没有宽度或高度。
所以在他们的代码中:
if(circleX < squareX) distance += pow(circleX - boxX,2); //x-axis
应该是
if(circleX < squareX) distance += pow(circleX - squareX,2); //x-axis
决定方块是否与圆重叠/碰撞的想法如下:
完整功能应如下所示:
//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)和(120)之间的距离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
答案 1 :(得分:2)
有3例:
首先确定圆心和矩形中心之间的距离。我们称之为距离D.
然后找到足够小以适合矩形内部的最大圆圈。它的直径等于矩形的高度或矩形的宽度(以较小者为准)。如果新圆的半径加上原始圆的半径小于距离D那么肯定会发生碰撞。
然后找到足够大的最小圆圈以包含整个矩形。这个圆的半径可以用毕达哥拉斯(从矩形中心到矩形的任何角落的距离)找到。如果这个新圆的半径加上原始圆的半径大于距离D那么就不会有任何碰撞。
如果这两个测试都没有给你答案;然后,两个形状都不完全在另一个内部,但它们可能重叠或不重叠;因此,您必须确定一个形状的边缘是否与另一个形状的边缘相交。要做到这一点,扩展所有矩形的边缘,使它们是无限长度(使用线段来描述一条线);并尝试通过将x或y“插入”圆形公式来计算这些无限长度线与圆周相交的位置(注意:您将找到没有交点,1个交点或2个交点)。如果有2个交叉点,则必须测试其中一个是否为边缘。
例如,如果矩形的上边缘位于y = 2
,则将y = 2
插入您的formala中以获得圆圈。如果你发现这条线在x = 3
和x = 6`处相交,那么测试3和6是否在矩形的左边缘和矩形的右边缘之间 - 如果它们是那么边缘圆圈与矩形的上边缘相交,然后发生碰撞。
如果对矩形的所有4个边进行“边缘交点”测试而未检测到碰撞,则无法检测到碰撞。