多边形算法中的点有时会给出错误的结果[关闭]

Posted

技术标签:

【中文标题】多边形算法中的点有时会给出错误的结果[关闭]【英文标题】:Point in Polygon algorithm giving wrong results sometimes [closed] 【发布时间】:2013-01-26 22:25:00 【问题描述】:

我在 *** 上看到了我在我的 php 代码中实现的“多边形中的点”光线追踪算法。大多数情况下,它运行良好,但在一些复杂的情况下,具有复杂的多边形和恶性点,它会失败,并且它说那个点不在多边形中。

例如: 你会发现 here 我的 Polygon 和 Point 类:pointInPolygon 方法在 Polygon 类中。在文件的末尾,有两个点应该位于给定的多边形内(在 Google 地球上为真)。第二个效果很好,但第一个有问题:( .

您可以使用this KML file 在 Google 地球上轻松检查多边形。

【问题讨论】:

我从这里得到了脚本:***.com/a/2922778/1527491。 【参考方案1】:

去过那里 :-) 我还浏览了 *** 的画中画建议,包括您的参考和 this thread。不幸的是,没有一个建议(至少我尝试过的建议)对于现实生活场景来说是完美的和足够的:比如用户在谷歌地图上徒手绘制复杂的多边形、“恶毒”的左右问题、负数等等。

画中画算法必须适用于所有情况,即使多边形由数十万个点组成(如县界、自然公园等)——无论多边形有多“疯狂”。

所以我最终构建了一个新算法,基于天文学应用程序的一些来源:

//Point class, storage of lat/long-pairs
class Point 
    public $lat;
    public $long;
    function Point($lat, $long) 
        $this->lat = $lat;
        $this->long = $long;
    


//the Point in Polygon function
function pointInPolygon($p, $polygon) 
    //if you operates with (hundred)thousands of points
    set_time_limit(60);
    $c = 0;
    $p1 = $polygon[0];
    $n = count($polygon);

    for ($i=1; $i<=$n; $i++) 
        $p2 = $polygon[$i % $n];
        if ($p->long > min($p1->long, $p2->long)
            && $p->long <= max($p1->long, $p2->long)
            && $p->lat <= max($p1->lat, $p2->lat)
            && $p1->long != $p2->long) 
                $xinters = ($p->long - $p1->long) * ($p2->lat - $p1->lat) / ($p2->long - $p1->long) + $p1->lat;
                if ($p1->lat == $p2->lat || $p->lat <= $xinters) 
                    $c++;
                
        
        $p1 = $p2;
    
    // if the number of edges we passed through is even, then it's not in the poly.
    return $c%2!=0;

说明性测试

$polygon = array(
    new Point(1,1), 
    new Point(1,4),
    new Point(4,4),
    new Point(4,1)
);

function test($lat, $long) 
    global $polygon;
    $ll=$lat.','.$long;
    echo (pointInPolygon(new Point($lat,$long), $polygon)) ? $ll .' is inside polygon<br>' : $ll.' is outside<br>';


test(2, 2);
test(1, 1);
test(1.5333, 2.3434);
test(400, -100);
test(1.01, 1.01);

输出:

2,2 is inside polygon 
1,1 is outside
1.5333,2.3434 is inside polygon 
400,-100 is outside
1.01,1.01 is inside polygon

距我在多个网站上切换到上述算法已有一年多的时间了。与“SO 算法”不同,到目前为止还没有任何投诉。在行动中看到它here(国家真菌学数据库,对不起丹麦人)。您可以绘制一个多边形,或选择一个“kommune”(一个县) - 最终将一个多边形与数千个点与数千个记录进行比较。

更新 请注意,此算法的目标是地理数据/纬度、经度,这可能非常精确(小数点后第 n 个),因此将“多边形内”视为 多边形内 - 而不是 多边形的边界时间>。 1,1 被认为是外部,因为它在边界上。 1.0000000001,1.01 不是。

【讨论】:

是的!我已经为 PiP 尝试了 3 种不同的算法,这是最好的。一个根本不起作用,另一个给出了不一致的结果,但这个看起来很可靠!干得好。 我不知道你是怎么写这个答案的,但是谢谢哥们工作得很好。 出色的工作......干得好 嗨,你能检查一下吗 - ***.com/questions/61302366/… 这个例子最好!我试过这两个:***.com/questions/5065039/find-point-in-polygon-php,assemblysys.com/php-point-in-polygon-algorithm,但没有一个是准确的。

以上是关于多边形算法中的点有时会给出错误的结果[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 的多边形算法中的点

计算多边形中的点并将结果写入 (Geo)Dataframe

顶点定义框算法中的点?

多边形特例中的点

算法设计与分析——凸多边形最优三角剖分

平面凸包Graham算法