|
一个判断两条多段线重叠的算法。希望大家给点意见或建议。
以下为源码:
// 判断两条多段线是否重叠//
// 返回值:-1——(pl1<pl2)
// 0——(pl1=pl2)
// 1——(pl1>pl2)
int PlineOverlap(AcDbPolyline* pl1, AcDbPolyline* pl2)
{
int rtn1(1), rtn2(1);
Acad::ErrorStatus es1, es2;
AcGePoint3d pt1, pt2;
double param1(0), param2(0);
int i,j;
// 先判断其中一条线的所有结点是否在另一条线上
for (i=0,j=1; j<pl1->numVerts(); i++,j++)
{
pl1->getPointAt(i, pt1);
pl1->getPointAt(j, pt2);
if (pl2->getParamAtPoint(pt1, param1)!=Acad::eOk
|| pl2->getParamAtPoint(pt2, param2)!=Acad::eOk)
{
es1 = Acad::ePointNotOnEntity;
break;
}
else
{ //再判断两条线的子段是否有交点
AcDbPolyline* pl2Sub = GetSplitPline(pl2, param1, param2);
if (HasInter(pt1, pt2, pl2Sub))
{
break;
}
rtn1 ++;
}
}
for (i=0,j=1; j<pl2->numVerts(); i++,j++)
{
pl2->getPointAt(i, pt1);
pl2->getPointAt(j, pt2);
if (pl1->getParamAtPoint(pt1, param1)!=Acad::eOk
|| pl1->getParamAtPoint(pt2, param2)!=Acad::eOk)
{
es2 = Acad::ePointNotOnEntity;
break;
}
else
{
AcDbPolyline* pl1Sub = GetSplitPline(pl1, param1, param2);
if (HasInter(pt1, pt2, pl1Sub))
{
break;
}
rtn2 ++;
}
}
if (rtn1==pl1->numVerts()
&& rtn2==pl2->numVerts())
{
return 0;
}
else if (rtn1==pl1->numVerts())
{
return -1;
}
else if (rtn2==pl2->numVerts())
{
return 1;
}
else
{
return (-99);
}
}
//判断线段与多段线是否有交点
BOOL HasInter(AcGePoint3d ptFrom, AcGePoint3d ptTo, AcDbPolyline* pl, BOOL bExtend=FALSE)
{
int i,j;
AcGePoint3d pt1, pt2;
for (i=0,j=1; j<pl->numVerts(); i++,j++)
{
pl->getPointAt(i, pt1);
pl->getPointAt(j, pt2);
ads_point inter;
int teston;
if (bExtend) teston=0;
else teston=1;
if (acdbInters(asDblArray(ptFrom), asDblArray(ptTo), asDblArray(pt1), asDblArray(pt2), teston, inter)==RTNORM)
{
return TRUE;
}
}
return FALSE;
}
//取中间段
AcDbPolyline* GetSplitPline(AcDbPolyline* pl, double param1, double param2)
{
AcGeDoubleArray params;
if (param1<param2)
{
params.append(param1);
params.append(param2);
}
else
{
params.append(param2);
params.append(param1);
}
AcDbVoidPtrArray segs;
if (pl->getSplitCurves(params, segs)==Acad::eOk)
{
if (segs.length()==1)
{
return static_cast<AcDbPolyline*>(segs.at(0));
}
else if (segs.length()==2)
{
if (params.at(0)==0)
{
return static_cast<AcDbPolyline*>(segs.at(0));
}
if (params.at(1)==(pl->numVerts()-1))
{
return static_cast<AcDbPolyline*>(segs.at(1));
}
}
else if (segs.length()==3)
{
return static_cast<AcDbPolyline*>(segs.at(1));
}
}
return pl;
} |
|