现在的位置: 首页 > 综合 > 正文

判段点是否在多边形内

2012年12月19日 ⁄ 综合 ⁄ 共 2368字 ⁄ 字号 评论关闭

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

 

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// 交点数为奇数,在区域内
}

更多相关内容:

 

【上篇】
【下篇】

抱歉!评论已关闭.