最近我遇到了一个小问题但是多边形的边是多边形内部的点?

我的意思是 - 目前我正在尝试在JS中实现2D geometry library以满足自定义需求,并且有方法,让我们说polygon.contains(点) .

所以我的问题是 - 当点位于多边形的一个边上时 - 结果该点位于多边形的内部或外部?顶点的附加问题:如果点位于多边形顶点的顶部 - 是在内部还是外部?

我用过的Algo取自here,看起来像:

int pnpoly(int nvert, float *vertx, float *verty, float testx, float testy)
{
    int i, j, c = 0;
    for (i = 0, j = nvert-1; i < nvert; j = i++) {
        if ( ((verty[i]>testy) != (verty[j]>testy)) &&
          (testx < (vertx[j]-vertx[i]) * (testy-verty[i]) / (verty[j] - verty[i]) + vertx[i]) )
           c = !c;
    }
    return c;
}

此外,该网站还有一个引用:

PNPOLY将平面划分为多边形内的点,并指向多边形外部的点 . 边界上的点被分类为内部或外部 .

它是完全正确的,在某些情况下它返回TRUE,并且在某些情况下返回FALSE .

实际上,这不是我需要的 . 所以我的问题开始扩大 - 当点位于多边形的边缘时,哪种行为是正确的 - 是内部还是外部 . 你有一个更好的算法可预测的行为吗?

UPDATE:

好的,我找到了另一个算法,称为“蜿蜒数字”并测试这个我只使用多边形和带整数值的点:

function isLeft(p0, p1, p2){
    return ( Math.round((p1.x - p0.x) * (p2.y - p0.y)) - Math.round((p2.x - p0.x) * (p1.y - p0.y)) );
}

function polygonContainsPoint(polygon, point){
    var i, j, pointi, pointj;
    var count = 0;
    var vertices = polygon.vertices;
    var length = vertices.length;
    for (i = 0; i < length; i++){
        j = (i + 1) % length;
        pointi = vertices[i];
        pointj = vertices[j];
        if (pointi.y > point.y){
            if (pointj.y <= point.y && (isLeft(pointi, pointj, point) < 0)){
                --count;
            }
        } else if (pointj.y > point.y && (isLeft(pointi, pointj, point) > 0)){
            ++count;
        }
    }
    return 0 !== count;
}

你可以看到没有分裂;乘法被包装到round()方法中,因此无法获得浮点错误 . 无论如何,我得到的结果与奇数算法相同 . 而且我认为我开始在这种奇怪的行为中看到“模式”:左边和上边可能会告诉该点在多边形内部,但是当你试图将点放在右边或底边之一时 - 它可能返回false .

这对我不好 . 也许你们中的一些人知道一些具有更可预测行为的算法?