我制定了一种碰撞检测算法,可以检测旋转的正方形是否发生碰撞。我正在努力了解如何解决这些冲突。我认为第一步是计算可以将两个正方形分开的最小平移向量(MTV)。
我认为,这样做的方法是通过计算正方形在被测轴上的投影的重叠,然后使用最小重叠的长度和该轴的角度来形成MTV。 / p>
问题是我的代码无法通过比较投影来工作,而是使用此代码来检测碰撞:
double DotProduct(Vector vector0, Vector vector1)
{
return (vector0.X * vector1.X) + (vector0.Y * vector1.Y);
}
bool TestIfPointIsInFrontOfEdge(int edgeNormalIndex, int vertexToTestIndex, Box observerBox, Box observedBox)
{
// if (v - a) · n > 0 then vertex is in front of edge
// v is the vertex to test
// a is a vertex on the edge that relates to the edge normal
// n is the edge normal
Vector v = new Vector(observedBox.vertices[vertexToTestIndex].X, observedBox.vertices[vertexToTestIndex].Y);
Vector a = new Vector(observerBox.vertices[edgeNormalIndex].X, observerBox.vertices[edgeNormalIndex].Y);
Vector n = observerBox.edgeNormals[edgeNormalIndex];
Vector vMinusA = Vector.Subtract(v, a);
double dotProduct = DotProduct(vMinusA, n);
//Console.WriteLine(dotProduct);
return dotProduct > 0;
}
bool TestIfAllPointsAreInFrontOfEdge(int edgeIndex, Box observerBox, Box observedBox)
{
for (int i = 0; i < observedBox.vertices.Length; i++)
{
if (!TestIfPointIsInFrontOfEdge(edgeIndex, i, observerBox, observedBox))
{
return false;
}
}
return true;
}
bool TestIfAllPointsAreInFrontOfAnyEdge(Box observerBox, Box observedBox)
{
for (int i = 0; i < observerBox.edgeNormals.Length; i++)
{
if (TestIfAllPointsAreInFrontOfEdge(i, observerBox, observedBox))
return true;
}
return false;
}
bool TestBoxOverlap(Box observerBox, Box observedBox)
{
if (TestIfAllPointsAreInFrontOfAnyEdge(observerBox, observedBox) || TestIfAllPointsAreInFrontOfAnyEdge(observedBox, observerBox))
return false;
return true;
}
每个Box包含一个由四个PointF对象组成的数组,这些对象代表顶点(Box.vertices)。它们还包含四个Vector对象的数组,这四个Vector对象是标准化的(单位)矢量,代表每个边缘的法线(Box.edgeNormals)。
然后我为每个框调用此函数以检查是否存在碰撞:
if (TestBoxOverlap(observerBox, observedBox))
{
narrowPhaseCollisionList.Add(collision);
}
collision是一个包含观察者框和观察者框的两元素数组。
那么我该如何计算MTV?
我该如何将其应用到盒子上?