Blogger Information
Blog 3
fans 0
comment 0
visits 5045
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
php判断坐标点是否在多边形内
₉₄₇的博客
Original
1560 people have browsed it
<?php  
//方法一
/**
 * 判断一个坐标是否在一个多边形内(由多个坐标围成的)
 * 基本思想是利用射线法,计算射线与多边形各边的交点,如果是偶数,则点在多边形外,否则
 * 在多边形内。还会考虑一些特殊情况,如点在多边形顶点上,点在多边形边上等特殊情况。
 * @param $point 指定点坐标
 * @param $pts 多边形坐标 顺时针方向
 */
function is_point_in_polygon($point, $pts) {
    $N = count($pts);
    $boundOrVertex = true; //如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true
    $intersectCount = 0; 
    $precision = 2e-10; //浮点类型计算时候与0比较时候的容差
    $p1 = 0;
    $p2 = 0;
    $p = $point; //测试点
    $p1 = $pts[0];
    for ($i = 1; $i <= $N; ++$i) {
        if ($p['lng'] == $p1['lng'] && $p['lat'] == $p1['lat']) {
            return $boundOrVertex;
        }
         
        $p2 = $pts[$i % $N];
        if ($p['lat'] < min($p1['lat'], $p2['lat']) || $p['lat'] > max($p1['lat'], $p2['lat'])) {
            $p1 = $p2; 
            continue;
        }
         
        if ($p['lat'] > min($p1['lat'], $p2['lat']) && $p['lat'] < max($p1['lat'], $p2['lat'])) {
            if($p['lng'] <= max($p1['lng'], $p2['lng'])){
                if ($p1['lat'] == $p2['lat'] && $p['lng'] >= min($p1['lng'], $p2['lng'])) {
                    return $boundOrVertex;
                }

                if ($p1['lng'] == $p2['lng']) {
                    if ($p1['lng'] == $p['lng']) {
                        return $boundOrVertex;
                    } else {
                        ++$intersectCount;
                    }
                } else {
                    $xinters = ($p['lat'] - $p1['lat']) * ($p2['lng'] - $p1['lng']) / ($p2['lat'] - $p1['lat']) + $p1['lng'];
                    if (abs($p['lng'] - $xinters) < $precision) {
                        return $boundOrVertex;
                    }
                     
                    if ($p['lng'] < $xinters) {
                        ++$intersectCount;
                    } 
                }
            }
        } else {
            if ($p['lat'] == $p2['lat'] && $p['lng'] <= $p2['lng']) {
                $p3 = $pts[($i+1) % $N]; 
                if ($p['lat'] >= min($p1['lat'], $p3['lat']) && $p['lat'] <= max($p1['lat'], $p3['lat'])) {
                    ++$intersectCount;
                } else {
                    $intersectCount += 2;
                }
            }
        }
        $p1 = $p2;
    }
 
    if ($intersectCount % 2 == 0) {
        return 0;   //在多边形外 返回0
    }
    return 1;       //在多边形内 返回1
}

  $arr=[
    [
        'lng'=>1,
        'lat'=>1
    ],
    [
        'lng'=>1,
        'lat'=>3
    ],
    [
          'lng'=>1.5,
          'lat'=>4
    ],
    [
          'lng'=>3,
          'lat'=>2
    ],
    [
          'lng'=>2,
          'lat'=>1
    ],  
  ];

  $point=[
      'lng'=>2,
      'lat'=>2
  ];
$a= is_point_in_polygon($point, $arr);
var_dump($a);



//方法二
/*判断函数,$arr放入多边形各个顶点的坐标,
$t为判断点的位置,$n为顶点坐标的个数-1;
若点在多边形内则返回1,否则返回0;
*/
    function inpolygon($arr,$t,$n){ 
        for($i = 0;$i<=$n;$i++){  
            $arr[$i][0]-=$t[0];  
            $arr[$i][1]-=$t[1];  
        }  
        $t1 = $arr[0][0]>=0?($arr[0][1]>=0?0:3):($arr[0][1]>=0?1:2);  
        for($sum =0,$i=1;$i<=$n;$i++){  
            if(!$arr[$i][0] && !$arr[$i][1]){  
                break;  
            }  
            $f = $arr[$i][1]*$arr[$i-1][0] - $arr[$i][0]*$arr[$i-1][1];  
            if(!$f && $arr[$i-1][0]*$arr[$i][0]<=0 && $arr[$i-1][1]*$arr[$i][1]<=0){  
                break;  
            }  
            $t2 = $arr[$i][0]>=0?($arr[$i][1]>=0?0:3):($arr[$i][1]>=0?1:2);  
            if($t2 == ($t1+1)%4){  
                $sum +=1;  
            }  
            else if($t2 == ($t1+3)%4){  
                $sum -=1;  
            }  
            else if($t2 == ($t1+2)%4){  
                if($f>0)$sum+=2;  
                else $sum-=2;  
            }  
            $t1 = $t2;  
        }  
        if($i<=$n || $sum){  
            return 1;  //点在多边形内则返回1
        }  
        return 0;  //点在多边形外则返回0
    }

    $arr = array(  
        array(1,1),  
        array(1,3),  
        array(1.5,4),  
        array(3,2),  
        array(2,1)
    );  
    $xy = array(1,2);  

    /*调用函数*/
    var_dump(inpolygon($arr,$xy,count($arr)-1));


Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post