三角形和AABB交叉口改进

时间:2018-01-09 16:48:03

标签: java math geometry 2d intersection

我需要检查AABB是否与三角形相交(它也是AABB但是有切边)

我看到一些关于此的帖子,我试着做一些有效的计算。 幸运的是我取得了成功,但我认为可以通过更好的设计使其更好或者完全不同的计算。

我目前的代码:

public static boolean intersectsWith(AxisAlignedBB bb, AxisAlignedBB bb0) {
    //bb is real AABB
    //bb0 is AABB, but I want to cut edges in calculation
    if(bb == null)
        return false;

    boolean fastCheck = (bb0.minY < bb.maxY && bb0.maxY > bb.minY) && (bb0.minX < bb.maxX && bb0.maxX > bb.minX) && (bb0.minZ < bb.maxZ && bb0.maxZ > bb.minZ);
    if(fastCheck)
        return true;

    Vector2 t0;
    Vector2 t1;
    Vector2 t2;

    Vector2 v0;
    Vector2 v1;
    Vector2 v2;
    Vector2 v3;

    t0 = new Vector2(bb0.minX, bb0.minY);
    t1 = new Vector2(bb0.maxX, bb0.minY);
    t2 = new Vector2((bb0.minX + bb0.maxX) / 2, bb.maxY);

    v0 = new Vector2(bb.minX, bb.minY);
    v1 = new Vector2(bb.minX, bb.maxY);
    v2 = new Vector2(bb.maxX, bb.minY);
    v3 = new Vector2(bb.maxX, bb.maxY);
    boolean r0 = pointInTriangle(v0, t0, t1, t2) || pointInTriangle(v1, t0, t1, t2) || pointInTriangle(v2, t0, t1, t2) || pointInTriangle(v3, t0, t1, t2);

    if(r0) {
        return true;
    }

    t0 = new Vector2(bb0.minZ, bb0.minY);
    t1 = new Vector2(bb0.maxZ, bb0.minY);
    t2 = new Vector2((bb0.minZ + bb0.maxZ) / 2, bb.maxY);

    v0 = new Vector2(bb.minZ, bb.minY);
    v1 = new Vector2(bb.minZ, bb.maxY);
    v2 = new Vector2(bb.maxZ, bb.minY);
    v3 = new Vector2(bb.maxZ, bb.maxY);

    return pointInTriangle(v0, t0, t1, t2) || pointInTriangle(v1, t0, t1, t2) || pointInTriangle(v2, t0, t1, t2) || pointInTriangle(v3, t0, t1, t2);
}

private static double sign(Vector2 p1, Vector2 p2, Vector2 p3)
{
    return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y);
}

private static boolean pointInTriangle(Vector2 pt, Vector2 v1, Vector2 v2, Vector2 v3)
{
    boolean b1, b2, b3;

    b1 = sign(pt, v1, v2) < 0.0f;
    b2 = sign(pt, v2, v3) < 0.0f;
    b3 = sign(pt, v3, v1) < 0.0f;

    return ((b1 == b2) && (b2 == b3));
}

我的AxisAlignedBB类:

private static class AxisAlignedBB {
    public double minX;
    public double minY;
    public double minZ;
    public double maxX;
    public double maxY;
    public double maxZ;

    public AxisAlignedBB(double minX, double minY, double minZ, double maxX, double maxY, double maxZ) {
        this.minX = minX;
        this.minY = minY;
        this.minZ = minZ;
        this.maxX = maxX;
        this.maxY = maxY;
        this.maxZ = maxZ;
    }
}

要测试的代码:

AxisAlignedBB rectangle = new AxisAlignedBB(/* custom coordinates */);
AxisAlignedBB triangle = new AxisAlignedBB(/* custom coordinates */);

boolean intersects = intersectsWith(rectangle, triangle);

0 个答案:

没有答案