<?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));
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号