欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【算法】判断一个点是否在不规则多边形内-php版

程序员文章站 2024-03-16 19:58:34
...

这是别人问到的一个问题,当时完全没有思路。因为平时工作中,基本上没有用到类似的方法。这其实是一个GIS系统中判断坐标是否在范围内的算法,主要用在配送中,如外卖、快递等是否属于自己的配送范围。仔细想想,这还真是常用到的一个算法,所以重新写了一次,以防下次用到。

实现这个算法,主要用到射线判断法。即在一个多边形上,无限延长x轴,看看与多边形的相交点。如果相交点为奇数,则在多边形内;如果为偶数,则在多边形外。参考算法:https://wrf.ecse.rpi.edu//Research/Short_Notes/pnpoly.html

PHP实现:


/**
 * @name 判断某点是否在多边形内
 * @param $areas 原始坐标点
 * @param $points 需要判断的坐标点
 * @return bool true-多边形内,false-多边形外
 */
function piontInPolygon($areas, $points)
{
    //print_r($points);
    //如果刚好在顶点
    $count = count($areas);
    for($i = 0; $i < $count; $i++){
        if($areas[$i][0] === $points[0] && $areas[$i][1] === $points[1]){
            //echo 'on point';
            return true;
        }
    }

    //取最边的四个点,判断点是否在边外
    $minX = $minY = $maxX = $maxY = 0;
    $vertX = $vertY = [];
    for($i = 0; $i < $count; $i++){
        $vertX[] = $areas[$i][0];
        $vertY[] = $areas[$i][1];

        $minX = $areas[$i][0] < $minX ? $areas[$i][0] : $minX;
        $maxX = $areas[$i][0] > $maxX ? $areas[$i][0] : $maxX;
        $minY = $areas[$i][1] < $minY ? $areas[$i][1] : $minY;
        $maxY = $areas[$i][1] > $maxY ? $areas[$i][1] : $maxY;
    }
    //echo '$minX:'.$minX.'---$maxX:'.$maxX.'---$minY:'.$minY.'----$maxY:'.$maxY;
    //如果在四边外
    if($points[0] < $minX || $points[0] > $maxX || $points[1] < $minY || $points[1] > $maxY){
        //echo 'outside';
        return false;
    }


    $c = false;
    //x射线,斜率
    for($x = 0, $y = $count-1; $x < $count; $y = $x++){
        if( ($vertY[$x] > $points[1]) != ($vertY[$y] > $points[1]) &&
            ($points[0] < ($vertX[$y] - $vertX[$x]) * ($points[1] - $vertY[$x]) / ($vertY[$y] - $vertY[$x]) + $vertX[$x] )
        ){
            $c = !$c;
        }
    }
    //var_dump($c);
    return $c;
}


//测试

$areas = [
    [1,1],
    [5,0],
    [8,0],
    [8,2],
    [5,7],
    [3,7]
];
//$points = [7,5];//false
$points = [2,3];//true
$data = piontInPolygon($areas, $points);
var_dump($data);
die();

 

相关标签: PHP php