确定笛卡尔网格上二维形状之间交点的最佳方法是什么?
What is the best way to determine an intersection between 2D shapes on a cartesian grid?
下面的函数应该确定 movingBall 结构的两个对象是否相互“接触”
bool areBallstouching(movingBall one, movingBall two)
{
int xMin, xMax, yMin, yMax;
int TxMin, TxMax, TyMin, TyMax;
xMin = one.xPosition - one.radius;
xMax = one.xPosition + one.radius;
yMin = one.yPosition - one.radius;
yMax = one.yPosition + one.radius;
//===================================
TxMin = two.xPosition - two.radius;
TxMax = two.xPosition + two.radius;
TyMin = two.yPosition - two.radius;
TyMax = two.yPosition + two.radius;
//=======================================
vector <int> xrange, yrange, Txrange, Tyrange;
bool xtouch = false; bool ytouch = false;
for (int i = xMin; i < xMax; i++)
{
xrange.push_back(i);
}
for (int i = yMin; i < yMax; i++)
{
yrange.push_back(i);
}
for (int i = TxMin; i < TxMax; i++)
{
Txrange.push_back(i);
}
for (int i = TyMin; i < TyMax; i++)
{
Tyrange.push_back(i);
}
for (int i = 0; i < xrange.size(); i++)
for (int j = 0; j < Txrange.size(); j++)
if (xrange[i] == Txrange[j])
xtouch = true;
for (int i = 0; i < yrange.size()-1; i++)
for (int j = 0; j < Tyrange.size()-1; j++)
if (yrange[i] == Tyrange[j])
ytouch = true;
if (xtouch == true && ytouch == true)
{
return true;
}
else
{
return false;
}
}
我推断,只有共享任意两个坐标的球才能相互接触。如果它们只共享一个 x 坐标,它们将垂直对齐,但最上面的球的底点不会接触最底下的球的顶点。如果它们只共享一个 y 坐标,它们将水平对齐,但最左边的球的最右边的点不会接触到最右边的球的最左边的点。
所附图片证明了这一推理。当我实现代码时,并没有达到我想要的结果。程序无法正确检测两个圆之间的交点。
从数学上讲,两个圆的接触点会将它们的中心位置分开的距离等于两个半径的总和。如下:
- 如果圆心之间的距离小于半径之和,则圆相交;
- 如果中心之间的距离大于半径之和,则圆不相交(或接触)。
因此,您只需要使用基本的毕达哥拉斯进行简单的距离计算。
float dx = two.xPosition - one.xPosition;
float dy = two.yPosition - one.yPosition;
float distsq = dx * dx + dy * dy; // square distance between centers
float r = one.radius + two.radius; // sum of radii
float rsq = r * r;
bool intersect_or_touch = (distsq <= rsq);
请注意,上面我们可以在平方距离和平方半径的范围内操作,以避免需要使用 sqrt
计算。
下面的函数应该确定 movingBall 结构的两个对象是否相互“接触”
bool areBallstouching(movingBall one, movingBall two)
{
int xMin, xMax, yMin, yMax;
int TxMin, TxMax, TyMin, TyMax;
xMin = one.xPosition - one.radius;
xMax = one.xPosition + one.radius;
yMin = one.yPosition - one.radius;
yMax = one.yPosition + one.radius;
//===================================
TxMin = two.xPosition - two.radius;
TxMax = two.xPosition + two.radius;
TyMin = two.yPosition - two.radius;
TyMax = two.yPosition + two.radius;
//=======================================
vector <int> xrange, yrange, Txrange, Tyrange;
bool xtouch = false; bool ytouch = false;
for (int i = xMin; i < xMax; i++)
{
xrange.push_back(i);
}
for (int i = yMin; i < yMax; i++)
{
yrange.push_back(i);
}
for (int i = TxMin; i < TxMax; i++)
{
Txrange.push_back(i);
}
for (int i = TyMin; i < TyMax; i++)
{
Tyrange.push_back(i);
}
for (int i = 0; i < xrange.size(); i++)
for (int j = 0; j < Txrange.size(); j++)
if (xrange[i] == Txrange[j])
xtouch = true;
for (int i = 0; i < yrange.size()-1; i++)
for (int j = 0; j < Tyrange.size()-1; j++)
if (yrange[i] == Tyrange[j])
ytouch = true;
if (xtouch == true && ytouch == true)
{
return true;
}
else
{
return false;
}
}
我推断,只有共享任意两个坐标的球才能相互接触。如果它们只共享一个 x 坐标,它们将垂直对齐,但最上面的球的底点不会接触最底下的球的顶点。如果它们只共享一个 y 坐标,它们将水平对齐,但最左边的球的最右边的点不会接触到最右边的球的最左边的点。
所附图片证明了这一推理。当我实现代码时,并没有达到我想要的结果。程序无法正确检测两个圆之间的交点。
从数学上讲,两个圆的接触点会将它们的中心位置分开的距离等于两个半径的总和。如下:
- 如果圆心之间的距离小于半径之和,则圆相交;
- 如果中心之间的距离大于半径之和,则圆不相交(或接触)。
因此,您只需要使用基本的毕达哥拉斯进行简单的距离计算。
float dx = two.xPosition - one.xPosition;
float dy = two.yPosition - one.yPosition;
float distsq = dx * dx + dy * dy; // square distance between centers
float r = one.radius + two.radius; // sum of radii
float rsq = r * r;
bool intersect_or_touch = (distsq <= rsq);
请注意,上面我们可以在平方距离和平方半径的范围内操作,以避免需要使用 sqrt
计算。