判断某个点是否在多边形内

  在网上看见了一些判断的算法,都是通过射线判断与多段线的交点的个数计算的,不过没有考虑到

射线正好通过多段线端点,即端点与交点重合的情况,这里对该算法进行完善

//判断交点位于多段线端点上时,与其2个相邻点分别构成的直线是否都在射线的同一侧
BOOL IsRemoveIntersectPnt(AcDbRay &pRay ,const AcDbPolyline &poly,int pntIndex,AcGePoint3dArray &IntersectPnts)
{
   BOOL result=TRUE;
   AcGePoint3d pnt;
   poly.getPointAt(pntIndex,pnt);
   AcGePoint3d adjacentPnt1,adjacentPnt2; //与端点相邻的2个端点
 
   if (0==pntIndex)  //如果是第1点
   {
      poly.getPointAt(1,adjacentPnt1);  //相邻点是第2点和最末点
   poly.getPointAt(poly.numVerts()-1,adjacentPnt2);
   }
    else if(poly.numVerts()-1==pntIndex)  //如果是最末1点
   {
   poly.getPointAt(pntIndex-1,adjacentPnt1);  //相邻点是最末点前1点和第1点
      poly.getPointAt(0,adjacentPnt2);
 }
 else
 {
   poly.getPointAt(pntIndex-1,adjacentPnt1);
   poly.getPointAt(pntIndex+1,adjacentPnt2);
 }
 
  AcGeVector3d vec;

  if (!pnt.isEqualTo(pRay.basePoint()))  //如果射线起点与交点不相同
    vec=pnt-pRay.basePoint();  //以这2点确定镜像向量
  else  //如果射线起点与交点相同
  {
     if (1==IntersectPnts.length()) //如果此时只有一个交点
     {
   return TRUE;
     }else{
         vec=IntersectPnts[1]-IntersectPnts[0];
  }
  }
     
    AcGePlane pl(pRay.basePoint(),vec.perpVector());
    //取2个相邻点中的任意一点A,以射线起点和构成的线为中线进行镜像
    //如果镜像后的点A'与相邻点中的另一点B的距离小于A与B的距离
    //则认为:交点与其2个相邻点分别构成的直线不在射线的同一侧
    //此时,该位于多段线端点上的交点有效,无需删除
    AcGePoint3d  adjacentPnt1Mirrored(adjacentPnt1);
    adjacentPnt1Mirrored.mirror(pl); 
    if (adjacentPnt2.distanceTo(adjacentPnt1)>adjacentPnt2.distanceTo(adjacentPnt1Mirrored))
    {
    result=FALSE;
    }
 
   return result;
}


BOOL ptInPoly(AcGePoint3d & pt, AcGePoint2dArray & verts,AcGeVector3d rayDir)
{

 AcDbPolyline poly(verts.length());
  Acad::ErrorStatus es;
    int i,j;
 for (i = 0; i < verts.length(); i++)
 {
       es=poly.addVertexAt(i, verts.at(i));
 }
 poly.setClosed(Adesk::kTrue);

 AcDbRay ray;
 ray.setBasePoint(pt);
 ray.setUnitDir(rayDir);
 AcGePoint3dArray points;
 es = poly.intersectWith(&ray, AcDb::kOnBothOperands, points);
   
 for (i=points.length()-1;i>=0;i--)
 {
  for ( j=0;j<poly.numVerts();j++)
  {
   AcGePoint3d  pnt;
   poly.getPointAt(j,pnt); 
   
   if (points[i].isEqualTo(pnt))  //如果射线的多段线的交点与多段线的某端点重合
   {
                if (IsRemoveIntersectPnt(ray,poly,j,points)) //判断这个交点是否有效
                   points.removeAt(i);
   }
  }
 }
   
 if (points.length() % 2)
   return TRUE;
 else
    return FALSE;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值