判断点是否在多边形内

判断点是否在多边形内有三个步骤:(转自csdn)

 
    第一步:判断这个点是不是就是多边形的端点;  
    第二步:判断这个点是不是落在多边形的边界上;  
    第三步:通过这个点横向作一平行射线,判断与多边形的交点数,如果交点是顶点,则交点数加一,结果如果是奇数,则该点落在多边形之内,如果是偶数,则反之。
 
    具体算法涉及向量叉积,具体这部分不详细说了,上网轻易查到,下面贴过主算法函数吧,参考很好用。
    还是来自于csdn的。
 
 
 
  const   double   INFINITY     =   1e10;    
  const   double   ESP   =   1e-5;    
  const   int   MAX_N           =   1000;    
   
   
  struct   Point   {    
        double   x,   y;    
  };    
   
  struct   LineSegment   {    
        Point   pt1,   pt2;    
  };
 
  inline   double   max(double   x,   double   y)    
  {    
        return   (x   >   y   ?   x   :   y);    
  }    
   
  inline   double   min(double   x,   double   y)    
  {    
        return   (x   <   y   ?   x   :   y);    
  }    
   
  //   计算叉乘   |P1P0|   ×   |P2P0|    
  double   Multiply(Point   p1,   Point   p2,   Point   p0)    
  {    
  return   (   (p1.x   -   p0.x)   *   (p2.y   -   p0.y)   -   (p2.x   -   p0.x)   *   (p1.y   -   p0.y)   );    
  }    
   
  //   判断线段是否包含点point    
  bool   IsOnline(Point   point,   LineSegment   line)    
  {    
  return(   (   fabs(Multiply(line.pt1,   line.pt2,   point))   <   ESP   )   &&    
  (   (   point.x   -   line.pt1.x   )   *   (   point.x   -   line.pt2.x   )   <=   0   )   &&    
  (   (   point.y   -   line.pt1.y   )   *   (   point.y   -   line.pt2.y   )   <=   0   )   );    
  }    
   
  //   判断线段相交    
  bool   Intersect(LineSegment   L1,   LineSegment   L2)    
  {    
  return(   (max(L1.pt1.x,   L1.pt2.x)   >=   min(L2.pt1.x,   L2.pt2.x))   &&    
                          (max(L2.pt1.x,   L2.pt2.x)   >=   min(L1.pt1.x,   L1.pt2.x))   &&    
                          (max(L1.pt1.y,   L1.pt2.y)   >=   min(L2.pt1.y,   L2.pt2.y))   &&    
                          (max(L2.pt1.y,   L2.pt2.y)   >=   min(L1.pt1.y,   L1.pt2.y))   &&    
                          (Multiply(L2.pt1,   L1.pt2,   L1.pt1)   *   Multiply(L1.pt2,   L2.pt2,   L1.pt1)   >=   0)   &&    
                          (Multiply(L1.pt1,   L2.pt2,   L2.pt1)   *   Multiply(L2.pt2,   L1.pt2,   L2.pt1)   >=   0)    
                      );    
  }    
   
   
  //   判断点在多边形内    
  bool   InPolygon(Point   polygon[],   int   n,   Point   point)    
  {    
          if   (n   ==   1)   {    
                return   (   (fabs(polygon[0].x   -   point.x)   <   ESP)   &&   (fabs(polygon[0].y   -   point.y)   <   ESP)   );    
  }   else   if   (n   ==   2)   {    
  LineSegment   side;    
  side.pt1   =   polygon[0];    
  side.pt2   =   polygon[1];    
  return   IsOnline(point,   side);    
  }    
   
  int   count   =   0;    
  LineSegment   line;    
  line.pt1   =   point;    
  line.pt2.y   =   point.y;    
  line.pt2.x   =   -   INFINITY;    
   
  for(   int   i   =   0;   i   <   n;   i++   )   {    
  //   得到多边形的一条边    
  LineSegment   side;    
  side.pt1   =   polygon[i];    
  side.pt2   =   polygon[(i   +   1)   %   n];    
   
  if(   IsOnline(point,   side)   )   {    
  return   true;    
  }    
   
  //   如果side平行x轴则不作考虑    
  if(   fabs(side.pt1.y   -   side.pt2.y)   <   ESP   )   {    
  continue;    
  }    
   
  if(   IsOnline(side.pt1,   line)   )   {    
  if(   side.pt1.y   >   side.pt2.y   )   count++;    
                  }   else   if(   IsOnline(side.pt2,   line)   )   {    
                          if(   side.pt2.y   >   side.pt1.y   )   count++;    
                  }   else   if(   Intersect(line,   side)   )   {    
                          count++;    
                  }    
          }    
   
          return   (   count   %   2   ==   1   );    
  }   
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冷月宫主

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值