博客列表 >判断坐标是否在区域内的算法

判断坐标是否在区域内的算法

二狗子的博客
二狗子的博客原创
2018年05月05日 11:03:042925浏览

function check($point, $polygon)
{
   //记录相交次数的计数器
   $count = 0;
   //记录顶点与测量点线段与x轴平行的次数
   $px = 0;
   //遍历多边形顶点
   for($i = 0; $i < count($polygon); $i++)
   {
       $p1 = $polygon[$i];//当前顶点
       $p2 = $polygon[($i + 1) % count($polygon)];//下一个顶点

       //如果两个顶点的y坐标均比测量点y坐标大,则跳过
       if($p1[1] > $point[1] && $p2[1] > $point[1])
       {
           continue;
       }
       //如果两个顶点的y坐标均比测量点y坐标小,则跳过
       if($p1[1] < $point[1] && $p2[1] < $point[1])
       {
           continue;
       }
       //如果测量点的y坐标在两个顶点的y坐标之间,或者如果测量点的x坐标在两个顶点的x坐标之间
       if((($point[1] > $p1[1]) != ($point[1] > $p2[1])) || (($point[0] > $p1[0]) != ($point[0] > $p2[0])))
       {
           //如果计算斜率的被除数均不为零
           if(($p1[0] - $p2[0]) != 0 && ($p1[0] - $point[0]) != 0)
           {
               //如果两条线段的斜率相等,则说明该点在两个顶点相连的边上,直接返回true
               if((($p1[1] - $p2[1]) / ($p1[0] - $p2[0])).'' == (($p1[1] - $point[1]) / ($p1[0] - $point[0])).'')
               {
                   return true;
               }
           }
           //如果两个被除数均为零,则该点也在两个顶点相连的线段上,直接返回true
           elseif(($p1[0] - $p2[0]) == 0 && ($p1[0] - $point[0]) == 0)
           {
               return true;
           }
       }

       //在排除点在线段上之后,若两个点的y坐标相等,说明与x轴平行,跳过当次循环
       if($p1[1] === $p2[1])
       {
           continue;
       }

       //根据斜率计算公式计算出相交点的x坐标
       $x = ($point[1] - $p1[1]) * ($p1[0] - $p2[0]) / ($p1[1] - $p2[1]) + $p1[0];

       //如果x坐标比测试点x坐标大,说明在测试点的右边,计数器加1
       if($x > $point[0])
       {
           $count++;
           // echo $p1[1].'   '.$point[1].'    '.$p2[1].'    '.$point[1]."\n";
           if($p1[1] == $point[1] || $p2[1] == $point[1])
           {
               $px++;
           }
       }
   }

   $count -= $px / 2;

   //echo "$count    :     $px \n";

   //如果相交点数量为偶数 则不在多边形内部 返回false,否则返回true
   if($count %2 === 0)
   {
       return false;
   }
   else
   {
       return true;
   }
}

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议