求任意多边形的内点的算法

来源:http://www.faqs.org/faqs/graphics/algorithms-faq/  
   
  下面是原文:  
    Subject   2.06:   How   do   I   find   a   single   point   inside   a   simple   polygon?  
   
        Given   a   simple   polygon,   find   some   point   inside   it.     Here   is   a   method  
        based   on   the   proof   that   there   exists   an   internal   diagonal,   in  
        [O'Rourke   (C),   13-14].     The   idea   is   that   the   midpoint   of   a   diagonal  
        is   interior   to   the   polygon.  
     
        1.   Identify   a   convex   vertex   v;   let   its   adjacent   vertices   be   a   and   b.  
        2.   For   each   other   vertex   q   do:  
        2a.   If   q   is   inside   avb,   compute   distance   to   v   (orthogonal   to   ab).  
        2b.   Save   point   q   if   distance   is   a   new   min.  
        3.   If   no   point   is   inside,   return   midpoint   of   ab,   or   centroid   of   avb.  
        4.   Else   if   some   point   inside,   qv   is   internal:   return   its   midpoint.  
     
        Code   for   finding   a   diagonal   is   in   [O'Rourke   (C),   35-39],   and   is   part  
        of   many   other   software   packages.     See   Subject   0.07:   Where   is   all   the    
        source?  
   
  其实实现并不复杂,其实楼上各位的算法要实现起来   代码量也不会比我的少。  
  下面是我以前写的程序:  
  /*  
  作者:阿里  
  日期:2002.10  
    给定一简单多边形,找出一个肯定在该多边形内的点  
  定理1:每个多边形至少有一个凸顶点  
  定理2:顶点数>=4的简单多边形至少有一条对角线  
  结论: x坐标最大,最小的点肯定是凸顶点  
              y坐标最大,最小的点肯定是凸顶点                      
  */  
  POINT   a_point_insidepoly(int   vcount,POINT   polygon[])  
  {  
        POINT   v,a,b,r;  
        int   i,index;  
        v=polygon[0];  
        index=0;  
        for(i=1;i<vcount;i++)                       //寻找一个凸顶点,实际上最低点肯定是凸顶点  
              {  
                    if(polygon[i].y<v.y)  
                          {  
                                v=polygon[i];  
                                index=i;  
                          }  
              }  
        a=polygon[(index-1+vcount)%vcount];               //得到v的前一个顶点  
        b=polygon[(index+1)%vcount];                             //得到v的后一个顶点  
        POINT   tri[3],q;  
        tri[0]=a;tri[1]=v;tri[2]=b;  
        double   md=INF;  
        int   in1=index;  
        bool   bin=false;  
        for(i=0;i<vcount;i++)                                 //寻找在三角形avb内且离顶点v最近的顶点q  
              {  
                    if(i   ==   index)continue;  
                    if(i   ==   (index-1+vcount)%vcount)continue;  
                    if(i   ==   (index+1)%vcount)continue;  
                    if(!InsideConvexPolygon(3,tri,polygon[i]))continue;  
                    bin=true;  
                    if(dist(v,polygon[i])<md)  
                          {  
          q=polygon[i];  
  md=dist(v,q);  
                          }  
              }  
        if(!bin)                                                         //没有顶点在三角形avb内,返回线段ab中点  
              {  
                    r.x=(a.x+b.x)/2;  
                    r.y=(a.y+b.y)/2;  
                    return   r;  
              }  
        r.x=(v.x+q.x)/2;                                         //返回线段vq的中点  
        r.y=(v.y+q.y)/2;  
        return   r;  
  }  
   
   
   
  上面的函数调用一个InsideConvexPolygon   函数,如下:  
  //   点q是凸多边形polygon内时,返回true;注意:多边形polygon一定要是凸多边形    
  //   否则要用射线法来判断,比较复杂  
  bool   InsideConvexPolygon(int   vcount,POINT   polygon[],POINT   q) //   可用于三角形!  
  {  
  POINT   p;  
  LINESEG   l;  
  int   i;  
  p.x=0;p.y=0;  
  for(i=0;i<vcount;i++)         //   寻找一个肯定在多边形polygon内的点p:多边形顶点平均值  
  {  
  p.x+=polygon[i].x;  
  p.y+=polygon[i].y;  
  }  
  p.x   /=   vcount;  
  p.y   /=   vcount;  
   
  for(i=0;i<vcount;i++)  
  {  
  l.s=polygon[i];l.e=polygon[(i+1)%vcount];  
  if(multiply(p,l.e,l.s)*multiply(q,l.e,l.s)<0)     /*   点p和点q在边l的两侧,说明  
  点q肯定在多边形外         */  
  break;  
  }  
  return   (i==vcount);  
  }  

 

原网页:http://topic.csdn.net/t/20030328/09/1587418.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值