|
一、本节课程
C++ ARX二次开发点和闭合多段线的位置关系
二、本节要讲解的知识点
结合自己的业务场景,想想自己开发中可能碰到的点和闭合多段线相对关系的需求:统计多段线内部的所有图块;还可以拓展判断任意曲线跟多段线的相对关系。
三、具体内容
计算机图形学、计算几何。判断点是否在多边形内部,一般有以下方法:
叉乘判断(适合凸多边形):如果将多边形的所有顶点按逆时针排序,那么判断点和每一条边的位置关系,如果点在多边形每一条边的左侧,那么点就在我们的多边形内部。
射线法:从给定点出发,沿着X轴正方向或者负方向做一条射线(射线可能跟多边形没有交点),计算射线跟多边形的交点数量,如果是奇数个交点,在内部;偶数个交点在外部。处理下点就在多边形的顶点上的特例。
本节提供的算法的思路是:
计算点到多段线的最近点,如果两点之间的距离少于容差,则认为点就在多段线上。
从给定点出发,沿最近点到给定点的方向做一个射线(之所以这么来做射线,是为了尽可能早可能早判断出点不在多边形内部的情况),计算射线和多段线的交点。
如果交点中包含了多段线的顶点,就将射线旋转2度继续进行判断;如果不包含多段线的顶点,则根据交点个数来判断点和多段线的位置关系。
在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。
|
|