分离轴定理

时间:2014-02-08 14:43:18

标签: java math geometry axis

我正试图解决这个问题 - 我一直在寻找一整天!

我想我理解它背后的主要概念,但是我正在努力弄清楚我需要创建的轴来将我的形状投射到轴上?

因此,如果我有一个矩形,我会找出每个点,然后使用它们找到形状edge = v(n) - v(n-1)的一侧并穿过所有边。

但我不知道如何创建分离轴。

2 个答案:

答案 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

检查另一个形状的顶点是否产生相反的符号。