判段点是否在多边形内

点在多边形内是几何,图形学,游戏领域经常用到的算法,算法的描述网上有很多,就是经过这点和多边形内一点连线,然后根据线与多边形的交点数目来判断,多的就不说了,直接来个源代码,大家用着方便

 

bool    IsPtInArea(AcGePoint3d pt, AcGePoint3dArray &  pt3dArr)
{
    
int  iLen  =  pt3dArr.length();
    
if  (iLen  <   3 )
        
return   false ;
    
//  首先构造最小包络面并得到最大 x 坐标
     int  i;
    
double  dblMaxX  =  pt3dArr[ 0 ].x;
    
double  dblMinX  =  pt3dArr[ 0 ].x;
    
double  dblMaxY  =  pt3dArr[ 0 ].y;
    
double  dblMinY  =  pt3dArr[ 0 ].y;
    
for  (i  =   1 ; i  <  iLen; i ++ )
    {
        
if  (pt3dArr[i].x  >  dblMaxX)
            dblMaxX 
=  pt3dArr[i].x;
        
if  (pt3dArr[i].x  <  dblMinX)
            dblMinX 
=  pt3dArr[i].x;
        
if  (pt3dArr[i].y  >  dblMaxY)
            dblMaxY 
=  pt3dArr[i].y;
        
if  (pt3dArr[i].y  <  dblMinY)
            dblMinY 
=  pt3dArr[i].y;
    }
    
//  如果点位于最小包络面之外,则肯定不在区域内,直接返回 false
     if  (( pt.x  >  dblMaxX)  ||
        ( pt.x 
<  dblMinX)  ||
        ( pt.y 
>  dblMaxY)  ||
        ( pt.y 
<  dblMinY)
        )
        
return   false ;

    
//  循环求取交点
    pt.z  =   0.0 ;
    AcGePoint3d xpt, ipt; 
    xpt 
=  pt;
    xpt.x 
=  dblMaxX  +   10.0 ;
    
// xpt.x = 1.7e208;
    AcGeLineSeg3d lineseg3d(pt, xpt);
    AcGePoint3d p1 
=  pt3dArr.first();

    p1.z 
=   0.0 ;
    
bool  bAdd  =   false ;
    
if  ( ! pt3dArr[iLen  -   1 ].isEqualTo(p1)){
        pt3dArr.append(p1);
        iLen
++ ;
        bAdd 
=   true ;
    }

    AcGePoint3d p2;
    
int  nCount  =   0 ;
    
for  (i = 1 ; i  <  iLen; i ++ )
    {
        p2 
=  pt3dArr[i];
        p2.z 
=   0.0 ;
        
//  如果所给点与顶点相等,直接返回
         if  (pt.isEqualTo(p1))
        {
            
if  (bAdd)
                pt3dArr.removeLast();
            
return   true ;
        }
        AcGeLineSeg3d xlineseg3d(p1, p2);
        
//  如果所给点在某一条边上,直接返回
         if  (xlineseg3d.isOn(pt)  ==  Adesk::kTrue)
        {
            
if  (bAdd)
                pt3dArr.removeLast();
            
return   true ;
        }
        
//  如果构造线段与交点存在,加入交点表
         if  (lineseg3d.intersectWith(xlineseg3d, ipt)  ==  Adesk::kTrue)
        {
            
// bool bAdd = true;
            
//  如果交点正好为顶点,判断另外的端点在哪一侧
             if  (ipt.isEqualTo(p1))
            {
                
if  (p2.y  >  ipt.y)
                    nCount
++ ;
            }
            
else   if (ipt.isEqualTo(p2))
            {
                
if  (p1.y  >  ipt.y)
                    nCount
++ ;
            }
            
else
                nCount
++ ;
        }
        p1 
=  p2;
    }

    
if  (bAdd)
        pt3dArr.removeLast();
    
    
if  ((nCount  %   2 ==   0 )
        
return   false //  交点数为偶数,不在区域内
     else
        
return   true //  交点数为奇数,在区域内
}

更多相关内容:

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值