C++ ARX二次开发点和闭合多段线的位置关系

一、本节课程
C++ ARX二次开发点和闭合多段线的位置关系

二、本节要讲解的知识点

结合自己的业务场景,想想自己开发中可能碰到的点和闭合多段线相对关系的需求:统计多段线内部的所有图块;还可以拓展判断任意曲线跟多段线的相对关系。

三、具体内容

  1. 计算机图形学、计算几何。判断点是否在多边形内部,一般有以下方法:
  1. 叉乘判断(适合凸多边形):如果将多边形的所有顶点按逆时针排序,那么判断点和每一条边的位置关系,如果点在多边形每一条边的左侧,那么点就在我们的多边形内部。
  2. 射线法:从给定点出发,沿着X轴正方向者负方向做一条射线(射线可能跟多边形没有交点),计算射线跟多边形的交点数量,如果是奇数个交点,在内部偶数个交点在外部。处理下点就在多边形的顶点上的特例。
  1. 本节提供的算法的思路是:
  1. 计算点到多段线的最近点,如果两点之间的距离少于容差,则认为点就在多段线上。
  2. 从给定点出发,沿最近点到给定点的方向做一个射线(之所以这么来做射线,是为了尽可能早可能早判断出点不在多边形内部的情况),计算射线和多段线的交点。
  3. 如果交点中包含了多段线的顶点,就将射线旋转2度继续进行判断;如果不包含多段线的顶点,则根据交点个数来判断点和多段线的位置关系。
  4. 在acrxEntryPoint.cpp文件中添加:

static void YunyouMyGroupTestPtInPoly()

      {

            int count=100000;

            AcDbEntity *pEnt=NULL;

            AcGePoint3d pickPoint;

            if (CSelectUtil::PromptSelctEnts(TEXT("\n选择需要进行测试的闭合多段线:"),AcDbPolyline::desc(),pEnt,pickPoint))

            {

                  AcDbExtents ext;

                  pEnt->getGeomExtents(ext);

                  double margin=10;

                  double xmin=ext.minPoint().x-margin;

                  double ymin=ext.minPoint().y-margin;

                  double xSpan=ext.maxPoint().x-ext.minPoint().x+2*margin;

                  double ySpan=ext.maxPoint().y-ext.minPoint().y+2*margin;

 

                  AcDbPolyline *pPoly=AcDbPolyline::cast(pEnt);

                  srand((unsigned)time(NULL));

                  for (int i=0;i<count;i++)

                  {

                        int maxRand=100000;

                        int xRand=CMathUtil::GetRand(0,maxRand);

                        int yRand=CMathUtil::GetRand(0,maxRand);

                        double x=xmin+((double)xRand/maxRand)*xSpan;

                        double y=ymin+((double)yRand/maxRand)*ySpan;

                        int relation=CPolylineUtil::PtRelationToPoly(pPoly,AcGePoint2d(x,y),1.0E-4);

                        int colorIndex=0;

                        switch (relation)

                        {

                        case -1:

                              colorIndex=1;

                              break;

                        case 0:

                              colorIndex=5;

                              break;

                        case 1:

                              colorIndex=6;

                              break;

                        default:

                              break;

                        }

                        AcDbPoint *pPoint=new AcDbPoint(AcGePoint3d(x,y,0));

                        pPoint->setColorIndex(colorIndex);

                        CDwgDatabaseUtil::PostToModelSpace(pPoint);

                  }

                  pEnt->close();

            }

      }

5、效果:随机生成了10万个点,在多边形内部和不在多边形内部的点用不同颜色都显示出来,是不是SO COOL。

(1)简单闭合多段线与随机点的关系

(2)有凸度复杂的多段线与随机点的关系图

(3)“云幽”多段线与随机点关系测试

四、总结

  1. 射线法判断点是否在多边形内部的原理。
  2. 利用随机数进行自动测试。

猜你喜欢

转载自blog.csdn.net/yunyouxy/article/details/81255861
今日推荐