0

我正在尝试使用分离轴定理在 Javascript/p5.js 中实现凹多边形的碰撞检测。我一直在关注如何使用它的以下教程:http ://www.dyn4j.org/2010/01/sat/

但是,无论两个多边形的位置如何,我的检查总是返回 true。这是我的代码:

function SAT(shape1, shape2)
{
    let axes1 = getAxes(shape1);
    let axes2 = getAxes(shape2);
    let colliding = true;
    for (let i = 0; i < axes1.length; i++)
    {
        let axis = axes1[i];
        let p1 = shape1.project(axis);
        let p2 = shape2.project(axis);
        if (!p1.overlap(p2)) colliding = false;
    }
    for (let i = 0; i < axes2.length; i++)
    {
        let axis = axes2[i];
        let p1 = shape1.project(axis);
        let p2 = shape2.project(axis);
        if (!p1.overlap(p2)) colliding = false;
    }
    return colliding;
}

function getAxes(shape)
{
    let axes = [];
    for (let i = 0; i < shape.vertices.length; i++)
    {
        let p1 = shape.vertices[i];
        let p2 = shape.vertices[i + 1 == shape.vertices.length ? 0 : i + 1];
        let edge = p1.sub(p2);
        let normal = createVector(-edge.y, edge.x);
        axes[i] = normal;
    }
    return axes;
}

class Projection
{

    constructor(min, max)
    {
        this.min = min;
        this.max = max;
    }

    overlap(other)
    {
        if (this.max < other.min || other.max < this.min) return false;
        else return true;
    }

}

class PolygonCollider extends Component
{

    constructor(gameObject)
    {
        super(gameObject);
        this.untransformedVertices = [];
        this.vertices = [];
        ...
    }

    setVerts(verts)
    {
        if (verts && verts.length > 2)
        {
            this.untransformedVertices = verts;
            this.vertices = this.transform.getTransformedPoints(verts);
            return this;
        }
        else return false;
    }

    project(axis)
    {
        let min = axis.dot(this.vertices[0]);
        let max = min;
        for (let i = 1; i < this.vertices.length; i++)
        {
            let p = axis.dot(this.vertices[i]);
            if (p < min) min = p;
            else if (p > max) max = p;
        }
        return new Projection(min, max);
    }

    update()
    {
        this.vertices = this.transform.getTransformedPoints(this.untransformedVertices);
    }

    ...

}

使用定义的比例、旋转和位置,使用以下函数转换顶点:

getTransformedPoints(points)
{
    let transformed = [];
    for (let i = 0; i < points.length; i++)
    {
        let rX = ((this.scale.x * points[i].x) * Math.cos(this.rotation)) - ((this.scale.y * points[i].y) * Math.sin(this.rotation));
        let rY = ((this.scale.x * points[i].x) * Math.sin(this.rotation)) + ((this.scale.y * points[i].y) * Math.cos(this.rotation));
        transformed[i] = createVector(rX + this.position.x, rY + this.position.y);
    }
    return transformed;
}

SAT 方法总是返回 true。我相信我正在错误地检查重叠,但我无法弄清楚我到底做错了什么。

4

1 回答 1

0

所以,我的实现的问题在于 p5.js,这是我在这种情况下使用的一个库。

在该方法中,我从使用 p5 的内置函数getAxes中减去。这没有达到预期的效果。我不确定,但我认为问题在于它没有创建一个新的向量,这就是方程的差异。我只是通过自己创建新向量来解决这个问题:p1p2p5.Vector.subcreateVector(p2.x - p1.x, p2.y - p1.y);

于 2018-06-20T01:04:04.973 回答