问题出现在函数中:
现在我不太关心优化。问题仍然存在:当围绕中心旋转时,碰撞检测无法正常进行。但是,如果中心点是
编辑:即使在碰撞检测之前进行旋转,我也遇到了同样的问题。 目前为止最好的方法是将多边形平移,使其质心位于
编辑:截图(这里的多边形被平移到它们的重心始终在
double Polygon::FindAxisLeastPenetration(unsigned int *faceIndex, const Polygon &polygonA, const Polygon &polygonB) const {
double bestDistance = -std::numeric_limits<double>::infinity();
unsigned int bestIndex;
for (unsigned int i = 0; i < polygonA.points.size(); i++) {
Vector2D n = polygonA.normals[i];
Vector2D nw = polygonA.rotationMatrix * n; //ROTATION
Matrix22 buT = polygonB.rotationMatrix.Transposed();
n = buT * nw; //ROTATION
Vector2D support = polygonB.points[polygonB.GetSupport(-n)];
Vector2D vertex = polygonA.points[i];
vertex = polygonA.rotationMatrix * vertex; //ROTATION
vertex.Add(polygonA.body->GetPosition());
vertex.Subtract(polygonB.body->GetPosition());
vertex = buT * vertex; // ROTATION
double distance = n.DotProduct(support - vertex);
if (distance > bestDistance) {
bestDistance = distance;
bestIndex = i;
}
}
*faceIndex = bestIndex;
return bestDistance;
}
unsigned int Polygon::GetSupport(const Vector2D &dir) const {
double bestProjection = -std::numeric_limits<double>::infinity();
unsigned int bestIndex = 0;
for (unsigned int i = 0; i < points.size(); i++) {
Vector2D vertex = points[i];
double projection = vertex.DotProduct(dir);
if (projection > bestProjection) {
bestProjection = projection;
bestIndex = i;
}
}
return bestIndex;
}
Manifold Polygon::CheckCollision(const Polygon &polygonA, const Polygon &polygonB) const {
Manifold result;
result.objectA = polygonA.body;
result.objectB = polygonB.body;
unsigned int indexA;
double penetrationA = Polygon::FindAxisLeastPenetration(&indexA, polygonA, polygonB);
if (penetrationA >= 0.0) {
result.intersects = false;
return result;
}
unsigned int indexB;
double penetrationB = Polygon::FindAxisLeastPenetration(&indexB, polygonB, polygonA);
if (penetrationB >= 0.0) {
result.intersects = false;
return result;
}
result.intersects = true;
//...
return result;
Rectangle::Rectangle(double width, double height) : Polygon() {
double hw = width / 2.0;
double hh = height / 2.0;
points.push_back(Vector2D(-hw, -hh));
points.push_back(Vector2D(hw, -hh));
points.push_back(Vector2D(hw, hh));
points.push_back(Vector2D(-hw, hh));
// points.push_back(Vector2D(0, 0));
// points.push_back(Vector2D(width, 0));
// points.push_back(Vector2D(width, height));
// points.push_back(Vector2D(0, height));
normals.push_back(Vector2D(0.0, -1.0));
normals.push_back(Vector2D(1.0, 0.0));
normals.push_back(Vector2D(0.0, 1.0));
normals.push_back(Vector2D(-1.0, 0.0));
center.x = 0;
center.y = 0;
polygon.rotationMatrix
是一个类型为Matrix22
的对象,它是一个2x2矩阵。
polygon.points
是填充有向量的std::vector<Vector2D>
。
polygon.body
是指向Object
实例的指针。在本例中,它仅用于获取位置。
polygon.body->position
是包含X
和Y
坐标的Vector2D
实例。
Vector2D polygon.body->GetPosition()
返回一个体的位置向量。
它的工作正常,唯一的问题是旋转是围绕[0, 0]
点进行的,但应该围绕质心旋转。
我知道,可以像这样围绕一个点进行旋转:
rotationMatrix * (vertex - point) + point
在渲染多边形时,它可以正常工作。但在碰撞检测中则不行。
在这种情况下,如何围绕某个点旋转向量?
编辑:以下是我目前的进展
double Polygon::FindAxisLeastPenetration(unsigned int *faceIndex, const Polygon &polygonA, const Polygon &polygonB) const {
double bestDistance = -std::numeric_limits<double>::infinity();
unsigned int bestIndex;
for (unsigned int i = 0; i < polygonA.points.size(); i++) {
// Calculate normal
unsigned int j = i == points.size() ? 0 : i + 1;
Vector2D n;
// Rotate points
Vector2D p1 = polygonA.rotationMatrix * (polygonA.points[i] - polygonA.Center()) + polygonA.Center();
Vector2D p2 = polygonA.rotationMatrix * (polygonA.points[j] - polygonA.Center()) + polygonA.Center();
n.x = p2.y - p1.y;
n.y = -(p2.x - p1.x);
n.Normalize();
Vector2D support = polygonB.points[polygonB.GetSupport(-n)];
support = polygonB.rotationMatrix * (support - polygonB.Center()) + polygonB.Center();
support.Add(polygonB.body->GetPosition());
Vector2D vertex = polygonA.points[i];
vertex = polygonA.rotationMatrix * (vertex - polygonA.Center()) + polygonA.Center(); //ROTATION
vertex.Add(polygonA.body->GetPosition());
double distance = n.DotProduct(support - vertex);
if (distance > bestDistance) {
bestDistance = distance;
bestIndex = i;
}
}
*faceIndex = bestIndex;
return bestDistance;
}
unsigned int Polygon::GetSupport(const Vector2D &dir) const {
double bestProjection = -std::numeric_limits<double>::infinity();
unsigned int bestIndex = 0;
for (unsigned int i = 0; i < points.size(); i++) {
Vector2D vertex = rotationMatrix * (points[i] - center) + center;
double projection = vertex.DotProduct(dir);
if (projection > bestProjection) {
bestProjection = projection;
bestIndex = i;
}
}
return bestIndex;
}
现在我不太关心优化。问题仍然存在:当围绕中心旋转时,碰撞检测无法正常进行。但是,如果中心点是
[0,0]
或者根本没有使用,则碰撞检测可以正常工作,但旋转仍然会出现错误。编辑:即使在碰撞检测之前进行旋转,我也遇到了同样的问题。 目前为止最好的方法是将多边形平移,使其质心位于
[0, 0]
,但在某些角度下无法检测到碰撞。现在不知道该怎么办了。编辑:截图(这里的多边形被平移到它们的重心始终在
[0,0]
,在这种情况下,多边形是矩形)
碰撞检测在这里运作不良
这里碰撞检测也无法正常工作
碰撞检测在这里正常工作
编辑:我添加了Rectangle
类。
points
是什么,它从哪里来?polygon.GetSupport()
是什么?polygon.body
和它的.position
是什么? - Nico Schertler//ROTATION
注释标记了旋转操作的行数。 - ivknv