- UID
- 242707
- 积分
- 62
- 精华
- 贡献
-
- 威望
-
- 活跃度
-
- D豆
-
- 在线时间
- 小时
- 注册时间
- 2005-4-13
- 最后登录
- 1970-1-1
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
合并两闭合的无自交的pline。
CAD本身也提供了域合并的功能,但是速度非常的慢。所以偶就自己写了试试,但是很多地方不好处理,如重线的处理还有漏洞,对于多个pline
的合并不好实现,因为对每两个返回的结果不知道怎么和其它的求交,而CAD的域合并返回的结果不管有多少的区域都作为一个处理.而且就算能完全正确,
速度也不会比CAD快, 求交点和判断点在区域的操作比较慢.各位如果有同样需求的不妨讨论一下,或者已有此类算法的高人请不吝赐教!
typedef CArray(AcGePoint3dArray,AcGePoint3dArray&) TPtArrArr;
typedef CArray(AcGeLineSeg3d,AcGeLineSeg3d&) TArrLineSeg3d;
"(" 为"<",显示不出来;
//点是否在区域内,bEdage--是否考虑边界
bool ptInArea(AcGePoint3d pt, AcGePoint3dArray& ptArr, bool bEdage = false);
//点表排序
bool sortPtb(AcGePoint3dArray & ptArr);
//取点距
double getDist(AcGePoint3d sp,AcGePoint3d ep);
//取中点
bool getMidPt(AcGePoint3d sp,AcGePoint3d ep,AcGePoint3d & midPt);
bool uniteSub(AcGePoint3dArray & ptArr1,AcGePoint3dArray & ptArr2,TPtArrArr & ptArrArr)
{
register int i,j,k;
int nLen1,nLen2;
AcGePoint3d pt,pt1;
AcGeLineSeg3d seg;
TArrLineSeg3d segArr,segArr1,segArr2;
ptArrArr.RemoveAll();
nLen1 = ptArr1.length();
nLen2 = ptArr2.length();
if((nLen1 < 3) || (nLen2 < 3))
return false;
//构造几何线段
for(i=1;i<nLen1;i++)
{
seg.set(ptArr1[i-1],ptArr1);
segArr1.Add(seg);
}
if (!ptArr1.first().isEqualTo(ptArr1.last()))
{
seg.set(ptArr1.last(),ptArr1.first());
segArr1.Add(seg);
}
for(i=1;i<nLen2;i++)
{
seg.set(ptArr2[i-1],ptArr2);
segArr2.Add(seg);
}
if (!ptArr2.first().isEqualTo(ptArr2.last()))
{
seg.set(ptArr2.last(),ptArr2.first());
segArr2.Add(seg);
}
bool bIn1,bIn2;
AcGePoint3dArray tmpArr;
//裁剪线段
bool bFlag;
for(k=0;k<2;k++)
{
//k==0用segArr2裁剪segArr1的各线段,k==1用segArr1裁剪segArr2的各线段
if (k == 1)
{
//互换顺序
segArr.RemoveAll();
segArr.Append(segArr1);
segArr1.RemoveAll();
segArr1.Append(segArr2);
segArr2.RemoveAll();
segArr2.Append(segArr);
if (tmpArr.length() > 0)
tmpArr.removeSubArray(0,tmpArr.length()-1);
tmpArr.append(ptArr1);
ptArr1.removeSubArray(0,ptArr1.length()-1);
ptArr1.append(ptArr2);
ptArr2.removeSubArray(0,ptArr2.length()-1);
ptArr2.append(tmpArr);
}
for(i=0;i<segArr1.GetSize();i++)
{
bIn1 = false;
bIn2 = false;
if(ptInArea(segArr1.startPoint(),ptArr2,false))
bIn1 = true;
if(ptInArea(segArr1.endPoint(),ptArr2,false))
bIn2 = true;
if(tmpArr.length() > 0)
tmpArr.removeSubArray(0,tmpArr.length()-1);
for(j=0;j<segArr2.GetSize();j++)
{
//相交线
if (segArr1.intersectWith(segArr2[j],pt))
{
//滤除交点是端点的情况
if(pt.isEqualTo(segArr1.startPoint()) || pt.isEqualTo(segArr1.endPoint()))
continue;
tmpArr.append(pt);
}
else//重合线
{
//对重合线的各种情况进行合并,考虑到效率,省略的函数和变量,写的比较累赘.
//这一部分对重合线的处理存在漏洞
if (segArr1.isOn(segArr2[j].startPoint()))
{
if (segArr1.isOn(segArr2[j].endPoint()))
{
bFlag = true;
if (getDist(segArr1.startPoint(),segArr2[j].startPoint()) < getDist(segArr1.startPoint(),segArr2[j].endPoint()))
{
seg.set(segArr2[j].endPoint(),segArr1.endPoint());
if(getDist(segArr1.startPoint(),segArr2[j].startPoint()) > 1.0E-7)
{
bFlag = false;
segArr1.set(segArr1.startPoint(),segArr2[j].startPoint());
}
if(seg.length() > 1.0E-7)
{
bFlag = false;
segArr1.Add(seg);
}
}
else
{
seg.set(segArr2[j].startPoint(),segArr1.endPoint());
if(getDist(segArr1.startPoint(),segArr2[j].endPoint()) > 1.0E-7)
{
bFlag = false;
segArr1.set(segArr1.startPoint(),segArr2[j].endPoint());
}
if(seg.length() > 1.0E-7)
{
bFlag = false;
segArr1.Add(seg);
}
}
segArr2.RemoveAt(j--);
if(bFlag)
{
segArr1.RemoveAt(i--);
break;
}
}
else if (segArr2[j].isOn(segArr1.startPoint()))
{
pt = segArr1.startPoint();
if(getDist(segArr1.endPoint(),segArr2[j].startPoint()) > 1.0E-7)
segArr1.set(segArr1.endPoint(),segArr2[j].startPoint());
if(getDist(pt,segArr2[j].endPoint()) > 1.0E-7)
segArr2[j].set(pt,segArr2[j].endPoint());
}
else if (segArr2[j].isOn(segArr1.endPoint()))
{
pt = segArr1.endPoint();
if(getDist(segArr1.startPoint(),segArr2[j].startPoint()) > 1.0E-7)
segArr1.set(segArr1.startPoint(),segArr2[j].startPoint());
if(getDist(pt,segArr2[j].endPoint()) > 1.0E-7)
segArr2[j].set(pt,segArr2[j].endPoint());
}
}
else if (segArr1.isOn(segArr2[j].endPoint()))
{
if (segArr2[j].isOn(segArr1.startPoint()))
{
pt = segArr1.startPoint();
if(getDist(segArr1.endPoint(),segArr2[j].endPoint()) > 1.0E-7)
segArr1.set(segArr1.endPoint(),segArr2[j].endPoint());
if(getDist(pt,segArr2[j].startPoint()) > 1.0E-7)
segArr2[j].set(pt,segArr2[j].startPoint());
}
else if (segArr2[j].isOn(segArr1.endPoint()))
{
pt = segArr1.endPoint();
if(getDist(segArr1.startPoint(),segArr2[j].endPoint()) > 1.0E-7)
segArr1.set(segArr1.startPoint(),segArr2[j].endPoint());
if(getDist(pt,segArr2[j].startPoint()) > 1.0E-7)
segArr2[j].set(pt,segArr2[j].startPoint());
}
}
else if (segArr2[j].isOn(segArr1.startPoint()) && segArr2[j].isOn(segArr1.endPoint()))
{
if (getDist(segArr2[j].startPoint(),segArr1.startPoint()) < getDist(segArr2[j].startPoint(),segArr1.endPoint()))
{
seg.set(segArr1.endPoint(),segArr2[j].endPoint());
if(getDist(segArr2[j].startPoint(),segArr1.startPoint()) > 1.0E-7)
segArr2[j].set(segArr2[j].startPoint(),segArr1.startPoint());
if(seg.length() > 1.0E-7)
segArr2.Add(seg);
}
else
{
seg.set(segArr1.startPoint(),segArr2[j].endPoint());
if(getDist(segArr2[j].startPoint(),segArr1.endPoint()) > 1.0E-7)
segArr2[j].set(segArr2[j].startPoint(),segArr1.endPoint());
if(seg.length() > 1.0E-7)
segArr2.Add(seg);
}
segArr1.RemoveAt(i--);
break;
}
}
}
//没有交点且该线段两端点不在另一区域中,删除该线段
if((tmpArr.length() <= 0) && bIn1 && bIn2)
{
segArr1.RemoveAt(i--);
continue;
}
else if (tmpArr.length() == 1)
{
//只有一的交点,分别裁剪两端
if (!bIn1)
{
if(getDist(segArr1.startPoint(),tmpArr.first()) > 1.0E-7)
segArr1.set(segArr1.startPoint(),tmpArr.first());
}
else if(!bIn2)
{
if(getDist(tmpArr.first(),segArr1.endPoint()) > 1.0E-7)
segArr1.set(tmpArr.first(),segArr1.endPoint());
}
}
else if (tmpArr.length() >= 2)
{
//有多个交点时,先裁剪两端,然后裁剪各段
//对交点排序
sortPtb(tmpArr);
//确定线段两端点与交点的点序
if(getDist(segArr1.startPoint(),tmpArr.first()) < getDist(segArr1.startPoint(),tmpArr.last()))
{
seg.set(tmpArr.last(),segArr1.endPoint());
if (!bIn1 && (getDist(segArr1.startPoint(),tmpArr.first()) > 1.0E-7))
segArr1.set(segArr1.startPoint(),tmpArr.first());
if (!bIn2 && (seg.length() > 1.0E-7))
segArr1.Add(seg);
}
else
{
seg.set(tmpArr.first(),segArr1.endPoint());
if (!bIn1 && (getDist(segArr1.startPoint(),tmpArr.last()) > 1.0E-7))
segArr1.set(segArr1.startPoint(),tmpArr.last());
if (!bIn2 && (seg.length() > 1.0E-7))
segArr1.Add(seg);
}
for(j=1;j<tmpArr.length();j++)
{
getMidPt(tmpArr[j-1],tmpArr[j],pt);
if (!ptInArea(pt,ptArr2,false))
{
seg.set(tmpArr[j-1],tmpArr[j]);
segArr1.Add(seg);
}
}
}
}
}
//构造闭合点组
bool bEqual,bClose;
segArr.RemoveAll();
segArr.Append(segArr1);
segArr.Append(segArr2);
while (segArr.GetSize() > 0)
{
if(tmpArr.length() > 0)
tmpArr.removeSubArray(0,tmpArr.length()-1);
tmpArr.append(segArr[0].startPoint());
tmpArr.append(segArr[0].endPoint());
segArr.RemoveAt(0);
bClose = false;
while (segArr.GetSize() > 0)
{
bEqual = false;
for(i=0;i<segArr.GetSize();i++)
{
if (tmpArr.last().isEqualTo(segArr.startPoint()))
{
bEqual = true;
tmpArr.append(segArr.endPoint());
segArr.RemoveAt(i--);
if (tmpArr.first().isEqualTo(tmpArr.last()))
{
bClose = true;
ptArrArr.Add(tmpArr);
}
break;
}
else if (tmpArr.last().isEqualTo(segArr.endPoint()))
{
bEqual = true;
tmpArr.append(segArr.startPoint());
segArr.RemoveAt(i--);
if (tmpArr.first().isEqualTo(tmpArr.last()))
{
bClose = true;
ptArrArr.Add(tmpArr);
}
break;
}
}
if(!bEqual || bClose)
break;
}
if(!bClose)
break;
}
if(ptArrArr.GetSize() <= 0)
{
ptArrArr.Add(ptArr1);
ptArrArr.Add(ptArr2);
}
return true;
}
bool sortPtb(AcGePoint3dArray & ptArr)
{
if (ptArr.isEmpty())
return false;
register int i,j,nLen;
nLen = ptArr.length();
for (i=0;i < nLen-1;i++)
{
for (j = i+1; j < nLen; j++)
{
if ((ptArr.x > ptArr[j].x) || ((fabs(ptArr.x-ptArr[j].x) < 1.0E-7) && (ptArr.y>ptArr[j].y)))
ptArr.swap(i,j);
}
}
return true;
} |
|