我正试图解决这个问题 - 我一直在寻找一整天!
我想我理解它背后的主要概念,但是我正在努力弄清楚我需要创建的轴来将我的形状投射到轴上?
因此,如果我有一个矩形,我会找出每个点,然后使用它们找到形状edge = v(n) - v(n-1)
的一侧并穿过所有边。
但我不知道如何创建分离轴。
答案 0 :(得分:2)
定理不难理解:如果你能找到一条线,其中所有形状点A都在一侧,而所有形状点B都在另一条线上(点积正或负),那条线将形状分开。
你想做什么?找到任意形状的分隔线?
我建议看看投影几何,因为扩展到无穷大的多边形的两个顶点的边可以用两个顶点(x,y,1)的叉积来表示。对于凸多边形,您可以简单地为所有边创建线,然后获取另一个多边形的所有顶点的点积来检查它们的哪一侧。如果对于一条边,所有点都在外面,那么该边是一条分隔线。
另请注意,通过保持线标准化,您可以使用点积获得点到线的距离。符号表示该点所在的一侧。
如果您的问题更加困难,请详细说明。也许你可以使用某种裁剪来快速解决它。
示例:投影几何
public double[] e2p(double x, double y) {
return new double[] { x, y, 1 };
}
// standard vector maths
public double[] getCrossProduct(double[] u, double[] v) {
return new double[] { u[1] * v[2] - u[2] * v[1],
u[2] * v[0] - u[0] * v[2], u[0] * v[1] - u[1] * v[0] };
}
public double getDotProduct(double[] u, double[] v) {
return u[0] * v[0] + u[1] * v[1] + u[2] * v[2];
}
// collision check
public boolean isCollision(List<Point2D> coordsA, List<Point2D> coordsB) {
return !(isSeparate(pointsA, pointsB) || isSeparate(pointsB, pointsA));
}
// the following implementation expects the convex polygon's vertices to be in counter clockwise order
private boolean isSeparate(List<Point2D> coordsA, List<Point2D> coordsB) {
edges: for (int i = 0; i < coordsA.size(); i++) {
double[] u = e2p(coordsA.get(i).getX(), coordsA.get(i).getY());
int ni = i + 1 < coordsA.size() ? i + 1 : 0;
double[] v = e2p(coordsA.get(ni).getX(), coordsA.get(ni).getY());
double[] pedge = getCrossProduct(u, v);
for (Point2D p : coordsB) {
double d = getDotProduct(pedge, e2p(p.getX(), p.getY()));
if (d > -0.001) {
continue edges;
}
}
return true;
}
return false;
}
答案 1 :(得分:0)
分离轴是其中一个侧面。当插入此方程式时,您可以找到形状顶点的符号:
(X - Xn).(Y - Yn-1) - (X - Xn-1).(Y - Yn) = 0
检查另一个形状的顶点是否产生相反的符号。