怎么求一个点是否在一个多边形内呢?

来源:互联网 发布:怎么做网络爬虫软件 编辑:程序博客网 时间:2024/04/29 16:52

假设我们有一个多边形Pn={p1,p2,p3,p4,p5,p6.......pn}

求一点p(x,y)是否在多边形内?

 

方法一:

            如果一个点在一个多边形之内,那么将该点与多边形的所有顶点相连接,这样就可以形成一些夹角,如:

      这些夹角之和(绝对值)则一定等于360度,所有只要求出这些夹角求和就行了。

      说明:求夹角的时候,可能会有负数,呵呵,因为我们需要确定一个旋转方向(以向量的概念),例如p_p1与p_p2的夹角是顺时针

     方向,则求其他夹角也要顺时针,这样求的和才会等于360度。

           其实你会发现,如果是一个正规的多边形的话,内部的点形成的夹角都是要么为正要么都为负数。

           当然:有的时候可能会有一些误差,所有我们需要有一个误差容忍度,例如为求和绝对值为360-0.00001和360+0.00001之间

方法二:

         反过来,我们可以考虑在多边形外面的点会怎么样?

      我们可以发现,求夹角其实就是沿着一个方向用一条线去穿过所有的线段,这样去求夹角,他们的夹角之和的绝对值是小于180度的。

 

 

  下面就看看怎么实现(方法二):

    1.夹角公式:

        参考说明:http://zhidao.baidu.com/question/37576001.html

     2.代码:

          const double PI=3.1415926535898;    //定义PI值

          //根据2个相对坐标求夹角

          double GetAngle(double x1,double y1,double x2,double y2)
         {

             double theta=0.0,theta1=0.0,theta2=0.0;

              theta1=atan2(y1,x1);      //tan(theta1)=y1/x1,求反正切值
              theta2=atan2(y2,x2);

 

              theta=theta1-theta2;      //获取夹角

              //返回的夹角值的绝对值要在(0,180)之间

              while(theta>PI)            
                   theta-=2*PI;
               while(theta<-PI)
                   theta+=2*PI;
               return theta;
           }

     3.定义结构体

        typedef struct PT
         {

             double x;
             double y;
         };

 

      4.main函数

          
int main()
{

 PT p1,p2,p3,p4,p5;
 p1.x=-1;
 p1.y=10;
 p2.x=-1;
 p2.y=-10;
 p3.x=-30;
 p3.y=0;
 p4.x=-20;
 p4.y=10;
 p5.x=-10;
 p5.y=13;

 PT p0;
 p0.x=-1.000007;
 p0.y=0;
 
 PT p[5]={p1,p2,p3,p4,p5};


 double angle=0.0;

 for(int i=0;i<4;i++)
 {
  p4.x=p[i].x-p0.x;
  p4.y=p[i].y-p0.y;

  p5.x=p[i+1].x-p0.x;
  p5.y=p[i+1].y-p0.y;

  if((p4.x==0&&p4.y==0)||(p5.x==0&&p5.y==0))//点在顶点上
  {
      cout<<"点在多边形一个顶点上"<<endl;
      break;
  }
  double temp=Angle2D(p4.x,p4.y,p5.x,p5.y);

  if(abs(temp)==PI)//点在边上
  {
      cout<<"点在多边形一条边上"<<endl;
       break;
  }
  else
  {
       angle+=temp;
  }

 }
 if(abs(angle)>=PI)//点在多边形内部
 {
  cout<<"点在多边形内"<<endl;
 }
 else
 {
  cout<<"点在多边形外"<<endl; 
 }
 return 0;

}

 

 

 

 

 

 

 

 

 

原创粉丝点击