#include "StdAfx.h" #ifdef TASD #include "TBaseWallIntegrateTool.h" #include "TBaseWallLine.h" double dTol = _AS_SYS_UNIT(20); typedef struct BaseWallLineParam { TBaseWallLine baseWallLine; double dParam; }BASEWALLLINEPARAM; static bool GreaterCompare(BaseWallLineParam& param1,BaseWallLineParam& param2) { if (param1.dParam - param2.dParam > 1.e-10) { return false; } return true; } // 判断是否是端点融合 // 返回值:0:两端不相交;1:起始端相交;2:终止端相交;3:两端都相交; int TBaseWallIntegrateTool::IsIntegrateAtTail(const TGGeCurveSegment& cvThis, const TGGeCurveSegment& cvThat) { int nRet = 0; //起始端 if(cvThis.StartPoint().Distance2d(cvThat.StartPoint()) < _DIST_SNAP ||cvThis.StartPoint().Distance2d(cvThat.EndPoint())< _DIST_SNAP) { nRet += 1; } //终止端 if(cvThis.EndPoint().Distance2d(cvThat.StartPoint()) < _DIST_SNAP ||cvThis.EndPoint().Distance2d(cvThat.EndPoint())< _DIST_SNAP) { nRet += 2; } return nRet; } // 双线普通融合 // 返回值:FALSE:融合不成功;1:融合成功; BOOL TBaseWallIntegrateTool::Integrate(TBaseWallLine& baseWallThis, const TBaseWallLine& baseWallThat) { TGGeVisibilityPoly2D lPoly = baseWallThis.GetLeftLine(); TGGeVisibilityPoly2D rPoly = baseWallThis.GetRightLine(); TGGeVisibilityPoly2D lPolyThat = baseWallThat.GetLeftLine(); TGGeVisibilityPoly2D rPolyThat = baseWallThat.GetRightLine(); BOOL nRet = FALSE; //函数状态,融合是否成功 bool bRetL = false; //左线是否修改 bool bRetR = false; //右线是否修改 AcGePoint3dArray ptArray, ptArray2, ptArray3, ptArray4; int nRet1 = InterSectWith(lPoly, lPolyThat, ptArray, AcDb::kOnBothOperands); int nRet2 = InterSectWith(lPoly, rPolyThat, ptArray2, AcDb::kOnBothOperands); int nRet3 = InterSectWith(rPoly, lPolyThat, ptArray3, AcDb::kOnBothOperands); int nRet4 = InterSectWith(rPoly, rPolyThat, ptArray4, AcDb::kOnBothOperands); if (nRet1 && nRet2 && nRet3 && nRet4) //双线十字相交 { if (baseWallThis.GetWeight() > baseWallThat.GetWeight()) { return TRUE; //当前双线优先级高,无需修改 } else { if (ptArray.length() > 0 && ptArray2.length() > 0) { //if(lPoly.PathDistance2d(ptArray[0]) > lPoly.PathDistance2d(ptArray2[0])) //{ // lPoly.InsertNodeAt(ptArray2[0], AcDb::kInvisible); // lPoly.InsertNodeAt(ptArray[0], AcDb::kVisible); //} //else //{ // lPoly.InsertNodeAt(ptArray[0], AcDb::kInvisible); // lPoly.InsertNodeAt(ptArray2[0], AcDb::kVisible); //} lPoly.InsertNodeAt(ptArray[0], ptArray2[0], AcDb::kInvisible); bRetL = true; } if (ptArray3.length() > 0 && ptArray4.length() > 0) { //if(rPoly.PathDistance2d(ptArray3[0]) > rPoly.PathDistance2d(ptArray4[0])) //{ // rPoly.InsertNodeAt(ptArray4[0], AcDb::kInvisible); // rPoly.InsertNodeAt(ptArray3[0], AcDb::kVisible); //} //else //{ // rPoly.InsertNodeAt(ptArray3[0], AcDb::kInvisible); // rPoly.InsertNodeAt(ptArray4[0], AcDb::kVisible); //} rPoly.InsertNodeAt(ptArray3[0], ptArray4[0], AcDb::kInvisible); bRetR = true; } } } else if (!(nRet1 || nRet2 || nRet3 || nRet4)) //不相交 { return FALSE; } else //丁字相交 { if ((nRet1 && nRet2) || (nRet3 && nRet4)) //丁字型中的横线 { if (baseWallThis.GetWeight() == baseWallThat.GetWeight()) { // 左线融合 if (ptArray.length() > 0 && ptArray2.length() > 0) { //if(lPoly.PathDistance2d(ptArray[0]) > lPoly.PathDistance2d(ptArray2[0])) //{ // lPoly.InsertNodeAt(ptArray2[0], AcDb::kInvisible); // lPoly.InsertNodeAt(ptArray[0], AcDb::kVisible); //} //else //{ // lPoly.InsertNodeAt(ptArray[0], AcDb::kInvisible); // lPoly.InsertNodeAt(ptArray2[0], AcDb::kVisible); //} lPoly.InsertNodeAt(ptArray[0], ptArray2[0], AcDb::kInvisible); bRetL = true; } // 右线融合 if (ptArray3.length() > 0 && ptArray4.length() > 0) { //if(rPoly.PathDistance2d(ptArray3[0]) > rPoly.PathDistance2d(ptArray4[0])) //{ // rPoly.InsertNodeAt(ptArray4[0], AcDb::kInvisible); // rPoly.InsertNodeAt(ptArray3[0], AcDb::kVisible); //} //else //{ // rPoly.InsertNodeAt(ptArray3[0], AcDb::kInvisible); // rPoly.InsertNodeAt(ptArray4[0], AcDb::kVisible); //} rPoly.InsertNodeAt(ptArray3[0], ptArray4[0], AcDb::kInvisible); bRetR = true; } } else { return TRUE; //当前双线优先级不同,无需修改 } } else //丁字型竖线,不显示 { if (nRet1 > 0) { double dist = lPoly.PathDistance2d(ptArray[0]); if (dist < lPoly.GetLength() - dist) //起始端不可见 { //lPoly.SetVisibleAt(0, AcDb::kInvisible); //lPoly.InsertNodeAt(ptArray[0], AcDb::kVisible); lPoly.InsertNodeAt(*lPoly[0], ptArray[0], AcDb::kInvisible); } else { //lPoly.InsertNodeAt(ptArray[0], AcDb::kInvisible); lPoly.InsertNodeAt(ptArray[0], *lPoly[lPoly.Length()-1], AcDb::kInvisible); } bRetL = true; } if (nRet2 > 0) { double dist = lPoly.PathDistance2d(ptArray2[0]); if (dist < lPoly.GetLength() - dist) //起始端不可见 { //lPoly.SetVisibleAt(0, AcDb::kInvisible); //lPoly.InsertNodeAt(ptArray2[0], AcDb::kVisible); lPoly.InsertNodeAt(*lPoly[0], ptArray2[0], AcDb::kInvisible); } else { //lPoly.InsertNodeAt(ptArray2[0], AcDb::kInvisible); lPoly.InsertNodeAt(ptArray2[0], *lPoly[lPoly.Length()-1], AcDb::kInvisible); } bRetL = true; } if (nRet3 > 0) { double dist = rPoly.PathDistance2d(ptArray3[0]); if (dist < rPoly.GetLength() - dist) //起始端不可见 { //rPoly.SetVisibleAt(0, AcDb::kInvisible); //rPoly.InsertNodeAt(ptArray3[0], AcDb::kVisible); rPoly.InsertNodeAt(*rPoly[0], ptArray3[0], AcDb::kInvisible); } else { //rPoly.InsertNodeAt(ptArray3[0], AcDb::kInvisible); rPoly.InsertNodeAt(ptArray3[0], *rPoly[rPoly.Length()-1], AcDb::kInvisible); } bRetR = true; } if (nRet4 > 0) { double dist = rPoly.PathDistance2d(ptArray4[0]); if (dist < rPoly.GetLength() - dist) //起始端不可见 { //rPoly.SetVisibleAt(0, AcDb::kInvisible); //rPoly.InsertNodeAt(ptArray4[0], AcDb::kVisible); rPoly.InsertNodeAt(*rPoly[0], ptArray4[0], AcDb::kInvisible); } else { //rPoly.InsertNodeAt(ptArray4[0], AcDb::kInvisible); rPoly.InsertNodeAt(ptArray4[0], *rPoly[rPoly.Length()-1], AcDb::kInvisible); } bRetR = true; } } } if (bRetL) { baseWallThis.SetLeftLine(lPoly); nRet = TRUE; } if (bRetR) { baseWallThis.SetRightLine(rPoly); nRet = TRUE; } return nRet; } // 双线尾端融合,baseWall2为实际发生相交的线,只在转角的情况考虑优先级,多分支暂时不考虑 BOOL TBaseWallIntegrateTool::IntegrateAtTail(bool bStart, TBaseWallLine& baseWallThis, const TBaseWallLine& baseWallThat) { using namespace std; TBaseWallLine* pSrcWall = &baseWallThis; // 原始墙线 const TBaseWallLine* pDesWall = &baseWallThat; if (pSrcWall == NULL || pDesWall == NULL) return FALSE; TGGeVisibilityPoly2D& plSrcLeft = pSrcWall->GetLeftLine(); TGGeVisibilityPoly2D& plSrcRight = pSrcWall->GetRightLine(); TGGeVisibilityPoly2D& plDesLeft = pDesWall->GetLeftLine(); TGGeVisibilityPoly2D& plDesRight = pDesWall->GetRightLine(); const int iWeightSrc = pSrcWall->GetWeight(); const int iWeightDes = pDesWall->GetWeight(); TGGeVisibilityPoly2D plRetLeft, plRetRight; vector > vPlRef; if (!ConfirmRelation(iWeightSrc - iWeightDes, &plSrcLeft, &plSrcRight, &plDesLeft, &plDesRight, vPlRef, bStart)) return FALSE; if (vPlRef.size() == 2) { pair& pairTmp1 = vPlRef.at(0); TGGeVisibilityPoly2D* pSrc1 = pairTmp1.first; const TGGeVisibilityPoly2D* pDes1 = pairTmp1.second; if (pSrc1 != NULL && pDes1 != NULL) if (ModifyPoly2D(*pSrc1, *pDes1, bStart)) plRetLeft = *pSrc1; pair& pairTmp2 = vPlRef.at(1); TGGeVisibilityPoly2D* pSrc2 = pairTmp2.first; const TGGeVisibilityPoly2D* pDes2 = pairTmp2.second; if (pSrc2 != NULL && pDes2 != NULL) if (ModifyPoly2D(*pSrc2, *pDes2, bStart)) plRetRight = *pSrc2; } baseWallThis.SetLeftLine(plRetLeft); baseWallThis.SetRightLine(plRetRight); return TRUE; } // 双线与poly2D的融合 // 返回值:FALSE:融合不成功;1:融合成功; BOOL TBaseWallIntegrateTool::Integrate(TBaseWallLine& baseWall, const TGGePoly2D& polyHole) { TGGeVisibilityPoly2D lPoly = baseWall.GetLeftLine(); TGGeVisibilityPoly2D rPoly = baseWall.GetRightLine(); TGGePoly2D poly = polyHole; if (lPoly.Length() > 0) { poly.SetElevation(lPoly[0]->z); } BOOL nRet = FALSE; AcGePoint3dArray ptArray; int nRet1 = InterSectWith(lPoly, poly, ptArray,AcDb::kOnBothOperands); if (nRet1 == 2) { if(ptArray[0].distanceTo(ptArray[1]) > _DIST_SNAP) { lPoly.InsertNodeAt(ptArray[0], ptArray[1], AcDb::kInvisible); baseWall.SetLeftLine(lPoly); nRet = TRUE; } } else if (nRet1 == 1) //1个交点时有可能交点是polyHole的顶点 { TADSGePoint3d ptStart = *lPoly[0]; TADSGePoint3d ptEnd = *lPoly[lPoly.Length()-1]; if ((ptEnd & polyHole) == PR_INSIDE) //终止端在polyHole内部 { lPoly.InsertNodeAt(ptArray[0], *lPoly[lPoly.Length()-1], AcDb::kInvisible); baseWall.SetLeftLine(lPoly); nRet = TRUE; } else if ((ptStart & polyHole) == PR_INSIDE) //起始端在polyHole内部 { lPoly.InsertNodeAt(*lPoly[0], ptArray[0], AcDb::kInvisible); baseWall.SetLeftLine(lPoly); nRet = TRUE; } } ptArray.setLogicalLength(0); if (rPoly.Length() > 0) { poly.SetElevation(rPoly[0]->z); } nRet1 = InterSectWith(rPoly, poly, ptArray,AcDb::kOnBothOperands); if (nRet1 == 2) { //if(rPoly.PathDistance2d(ptArray[0]) > rPoly.PathDistance2d(ptArray[1])) //{ // rPoly.InsertNodeAt(ptArray[1], AcDb::kInvisible); // rPoly.InsertNodeAt(ptArray[0], AcDb::kVisible); //} //else //{ // rPoly.InsertNodeAt(ptArray[0], AcDb::kInvisible); // rPoly.InsertNodeAt(ptArray[1], AcDb::kVisible); //} if(ptArray[0].distanceTo(ptArray[1]) > _DIST_SNAP) { rPoly.InsertNodeAt(ptArray[0], ptArray[1], AcDb::kInvisible); baseWall.SetRightLine(rPoly); nRet = TRUE; } } else if (nRet1 == 1) { TADSGePoint3d ptStart = *rPoly[0]; if ((ptStart & polyHole) == PR_OUTSIDE) //终止端在polyHole内部 { //rPoly.InsertNodeAt(ptArray[0], AcDb::kInvisible); rPoly.InsertNodeAt(ptArray[0], *rPoly[rPoly.Length()-1], AcDb::kInvisible); } else { //rPoly.InsertNodeAt(ptArray[0], AcDb::kVisible); //rPoly.SetVisibleAt(0, AcDb::kInvisible); rPoly.InsertNodeAt(*rPoly[0], ptArray[0], AcDb::kInvisible); } baseWall.SetRightLine(rPoly); nRet = TRUE; } return nRet; } int TBaseWallIntegrateTool::InterSectWith(const TGGePoly2D& polyThis, const TGGePoly2D& polyThat, AcGePoint3dArray &ptArray, AcDb::Intersect intType) { AcDbCurve* pCurveThis = polyThis.AsAcDbCurve(); AcDbCurve* pCurveThat = polyThat.AsAcDbCurve(); ptArray.setLogicalLength(0); if (pCurveThis && pCurveThat) { pCurveThis->intersectWith(pCurveThat, intType, ptArray); } if (pCurveThis) { delete pCurveThis; } if (pCurveThat) { delete pCurveThat; } return ptArray.length(); } ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// const TGGePoly2D* TBaseWallIntegrateTool::GetNearestPoly2DByTail(const TGGePoly2D* plSrc, const TGGePoly2D* pl1, const TGGePoly2D* pl2, bool bNearest) { if (plSrc == NULL || pl1 == NULL || pl2 == NULL) return NULL; if (plSrc->TotalSegments() < 1 || pl1->TotalSegments() < 1 || pl2->TotalSegments() < 1) return NULL; // 构造plSrc尾端线段 const TGGePoly2D& SrcPline = *plSrc; int iLen = SrcPline.TotalSegments(); const TADSGePoint3d& ptE = SrcPline[0]; // 从plSrc起始点计算到pl1和pl2的距离, 因为plSrc尾端可能在pl1和pl2的中间! const TGGePoly2D& plDes1 = *pl1; const TGGePoly2D& plDes2 = *pl2; int idx(-1); TGGeCurveSegment seg1(LS_INFINITE), seg2(LS_INFINITE); if (!GetSegByNearestPt(plDes1, ptE, seg1, idx)) return FALSE; if (!GetSegByNearestPt(plDes2, ptE, seg2, idx)) return FALSE; TADSGePoint3d ptProj1, ptProj2; seg1.ProjectToMe(ptE, ptProj1); seg2.ProjectToMe(ptE, ptProj2); double dDist1 = ptProj1.Distance2d(ptE); double dDist2 = ptProj2.Distance2d(ptE); if (bNearest) return (dDist1 - dDist2 <= _DIST_SNAP) ? pl1 : pl2; else return (dDist1 - dDist2 <= _DIST_SNAP) ? pl2 : pl1; return NULL; } const TGGePoly2D* TBaseWallIntegrateTool::GetDesPoly2D(const TGGePoly2D* plSrc, const TGGePoly2D* pl1, const TGGePoly2D* pl2, bool bStart, bool bNearest) { if (plSrc == NULL || pl1 == NULL || pl2 == NULL) return NULL; int iSrc = plSrc->TotalSegments(); int iDes1 = pl1->TotalSegments(); int iDes2 = pl2->TotalSegments(); if (iSrc < 1 || iDes2 < 1 || iDes1 < 1) return NULL; const AcGePoint3d& ptRef = bStart ? (*plSrc)[0] : (*plSrc)[iSrc]; // src上面定位指定端点 const TGGePoly2D& SrcPline = *plSrc; const TGGePoly2D& plDes1 = *pl1; const TGGePoly2D& plDes2 = *pl2; int idx(-1); TGGeCurveSegment seg1(LS_INFINITE), seg2(LS_INFINITE); if (!GetSegByNearestPt(plDes1, ptRef, seg1, idx)) return FALSE; if (!GetSegByNearestPt(plDes2, ptRef, seg2, idx)) return FALSE; TADSGePoint3d ptProj1, ptProj2; seg1.ProjectToMe(ptRef, ptProj1); seg2.ProjectToMe(ptRef, ptProj2); double dDist1 = ptProj1.Distance2d(ptRef); double dDist2 = ptProj2.Distance2d(ptRef); if (bNearest) return (dDist1 - dDist2 <= _DIST_SNAP) ? pl1 : pl2; else return (dDist1 - dDist2 <= _DIST_SNAP) ? pl2 : pl1; return NULL; } bool TBaseWallIntegrateTool::ModifyPoly2D(TGGeVisibilityPoly2D& plSrc, const TGGeVisibilityPoly2D& plDes, bool bStart) { const int iSrcLen = plSrc.TotalSegments(); const int iDesLen = plDes.TotalSegments(); if (iSrcLen < 1 || iDesLen < 1) return false; AcGePoint3d& ptSrcRef = bStart ? *plSrc[0] : *plSrc[iSrcLen]; // 起点或者终点 TGGeCurveSegment segSrc(LS_INFINITE), segDes(LS_INFINITE); // 获得src的延伸段儿 if (plSrc.Nth(bStart ? 0 : iSrcLen - 1, segSrc) != RTNORM) return false; // 选择des的延伸段儿 int iDes(-1); if (!GetSegByNearestPt(plDes, ptSrcRef, segDes, iDes)) return false; TGGeVisibilityPoly2D& pl = const_cast(plDes); double dLeft(0), dRight(0); if (!(plSrc.GetIDirection(ptSrcRef, dLeft) && pl.GetIDirection(ptSrcRef, dRight))) return false; dLeft = AngleRangeTo2PI(dLeft - dRight); if (fabs(dLeft - PI) < g_angleZero) { // 尾端平行情况 if (segSrc.Is(CURVE_LINE) && segDes.Is(CURVE_ARC)) { const AcGePoint3d& ptDes = GetDesPt(ptSrcRef, *pl[0], *pl[iDesLen]); TADSGePoint3d ptRet; segSrc.ProjectToMe(ptDes, ptRet); return MovePoly2DDesPt(plSrc, ptRet, bStart); } else if (segSrc.Is(CURVE_ARC)) return true; // src弧线不做任何修改 } // 延伸求交点, 求出需要延伸到的1个交点 TADSGePoint3d ptExt1, ptExt2; // 延伸求交的两个点 int iRetExt = segSrc.Intersection(segDes, ptExt1, ptExt2); if (iRetExt == 2) ptExt1 = GetDesPt(ptSrcRef, ptExt1, ptExt2); else if (iRetExt == 0) { // 没有交点, 进行投影求 const AcGePoint3d& ptVisual = GetDesPt(ptSrcRef, segDes.StartPoint(), segDes.EndPoint()); if (segSrc.ProjectToMe(ptVisual, ptExt1) != RTNORM) return false; } // 移动多段线的端点 return MovePoly2DDesPt(plSrc, ptExt1, bStart); } // iSeg指示在原来多短线上面的第几段 // ptNearest距离pt最近的点 bool TBaseWallIntegrateTool::GetSegByNearestPt(const TGGePoly2D& plDes, const AcGePoint3d& pt, TGGeCurveSegment& seg, int& iSeg) { int iLen = plDes.TotalSegments(); if (iLen < 1) return false; const AcGePoint3d& ptS = plDes[0]; const AcGePoint3d& ptE = plDes[iLen]; double dDist1 = pt.distanceTo(ptS); double dDist2 = pt.distanceTo(ptE); iSeg = 0; if (dDist2 - dDist1 < _DIST_SNAP) { iSeg = iLen - 1; } if (plDes.Nth(iSeg, seg) != RTNORM) return false; return true; } bool TBaseWallIntegrateTool::ConfirmRelation(int nEqual, TGGeVisibilityPoly2D* pSrcLeft, TGGeVisibilityPoly2D* pSrcRight, \ TGGeVisibilityPoly2D* pDesLeft, TGGeVisibilityPoly2D* pDesRight, \ std::vector >& vPlRef, \ bool bStart) { if (pSrcLeft == NULL || pSrcRight == NULL || pDesLeft == NULL || pDesRight == NULL) return false; int iLenLeft = pSrcLeft->TotalSegments(); int iLenRight = pSrcRight->TotalSegments(); int iDesLeft = pDesLeft->TotalSegments(); int iDesRight = pDesRight->TotalSegments(); if (iLenLeft < 1 || iLenRight < 1 || iDesLeft < 1 || iDesRight < 1) return false; const AcGePoint3d& ptSrcRef = bStart ? *(*pSrcLeft)[0] : *(*pSrcLeft)[iLenLeft]; // src左线参考点 const AcGePoint3d& ptDesS = *(*pDesLeft)[0]; // des起始点 const AcGePoint3d& ptDesE = *(*pDesLeft)[iDesLeft]; // des终止点 double dDist1 = ptSrcRef.distanceTo(ptDesS); double dDist2 = ptSrcRef.distanceTo(ptDesE); typedef std::pair pairPLine; pairPLine pair1, pair2; bool bAsEqual(nEqual == 0); if (dDist1 - dDist2 <= _DIST_SNAP) { // Des的起始端 if (nEqual != 0) { // 不等优先级 double dLeft(0), dRight(0); if (!(pSrcLeft->GetIDirection(ptSrcRef, dLeft)&&pDesLeft->GetIDirection(ptSrcRef, dRight))) return false; dLeft = AngleRangeTo2PI(dLeft - dRight); if (fabs(dLeft-PI) < g_angleZero) { // 尾端平行情况 bAsEqual = true; } else { TGGeCurveSegment segSrcL(LS_INFINITE), segSrcR(LS_INFINITE), segDes(LS_INFINITE); pSrcLeft->Nth(bStart ? 0 : iLenLeft - 1, segSrcL); pSrcRight->Nth(bStart ? 0 : iLenRight - 1, segSrcR); if (dLeft < PI) { if (nEqual < 0) { pDesLeft->Nth(iDesLeft - 1, segDes); if (segSrcL.Is(CURVE_ARC)||segDes.Is(CURVE_ARC)) { if (segDes.Intersection(segSrcL, TADSGePoint3d(), TADSGePoint3d()) == 0 || segDes.Intersection(segSrcR, TADSGePoint3d(), TADSGePoint3d()) == 0) { bAsEqual = true; } } if (!bAsEqual) { pair1 = pairPLine(pSrcLeft, pDesLeft); pair2 = pairPLine(pSrcRight, pDesLeft); } } else { pDesRight->Nth(iDesRight - 1, segDes); if (segSrcL.Is(CURVE_ARC)||segDes.Is(CURVE_ARC)) { if (segDes.Intersection(segSrcL, TADSGePoint3d(), TADSGePoint3d()) == 0 || segDes.Intersection(segSrcR, TADSGePoint3d(), TADSGePoint3d()) == 0) { bAsEqual = true; } } if (!bAsEqual) { pair1 = pairPLine(pSrcLeft, pDesRight); pair2 = pairPLine(pSrcRight, pDesRight); } } } else { if (nEqual < 0) { pDesRight->Nth(iDesRight - 1, segDes); if (segSrcL.Is(CURVE_ARC)||segDes.Is(CURVE_ARC)) { if (segDes.Intersection(segSrcL, TADSGePoint3d(), TADSGePoint3d()) == 0 || segDes.Intersection(segSrcR, TADSGePoint3d(), TADSGePoint3d()) == 0) { bAsEqual = true; } } if (!bAsEqual) { pair1 = pairPLine(pSrcLeft, pDesRight); pair2 = pairPLine(pSrcRight, pDesRight); } } else { pDesLeft->Nth(iDesLeft - 1, segDes); if (segSrcL.Is(CURVE_ARC)||segDes.Is(CURVE_ARC)) { if (segDes.Intersection(segSrcL, TADSGePoint3d(), TADSGePoint3d()) == 0 || segDes.Intersection(segSrcR, TADSGePoint3d(), TADSGePoint3d()) == 0) { bAsEqual = true; } } if (!bAsEqual) { pair1 = pairPLine(pSrcLeft, pDesLeft); pair2 = pairPLine(pSrcRight, pDesLeft); } } } } } if (bAsEqual) { // 等优先级处理 if (bStart) { pair1 = pairPLine(pSrcLeft, pDesRight); pair2 = pairPLine(pSrcRight, pDesLeft); } else { pair1 = pairPLine(pSrcLeft, pDesLeft); pair2 = pairPLine(pSrcRight, pDesRight); } } } else { // Des的终止端 if (nEqual != 0) { double dLeft(0), dRight(0); if (!(pSrcLeft->GetIDirection(ptSrcRef, dLeft)&&pDesLeft->GetIDirection(ptSrcRef, dRight))) return false; dLeft = AngleRangeTo2PI(dLeft - dRight); if (fabs(dLeft-PI) < g_angleZero) { bAsEqual = true; } else { TGGeCurveSegment segSrcL(LS_INFINITE), segSrcR(LS_INFINITE), segDes(LS_INFINITE); pSrcLeft->Nth(bStart ? 0 : iLenLeft - 1, segSrcL); pSrcRight->Nth(bStart ? 0 : iLenRight - 1, segSrcR); if (dLeft < PI) { if (nEqual < 0) { pDesRight->Nth(iDesRight - 1, segDes); if (segSrcL.Is(CURVE_ARC)||segDes.Is(CURVE_ARC)) { if (segDes.Intersection(segSrcL, TADSGePoint3d(), TADSGePoint3d()) == 0 || segDes.Intersection(segSrcR, TADSGePoint3d(), TADSGePoint3d()) == 0) { bAsEqual = true; } } if (!bAsEqual) { pair1 = pairPLine(pSrcLeft, pDesRight); pair2 = pairPLine(pSrcRight, pDesRight); } } else { pDesLeft->Nth(iDesLeft - 1, segDes); if (segSrcL.Is(CURVE_ARC)||segDes.Is(CURVE_ARC)) { if (segDes.Intersection(segSrcL, TADSGePoint3d(), TADSGePoint3d()) == 0 || segDes.Intersection(segSrcR, TADSGePoint3d(), TADSGePoint3d()) == 0) { bAsEqual = true; } } if (!bAsEqual) { pair1 = pairPLine(pSrcLeft, pDesLeft); pair2 = pairPLine(pSrcRight, pDesLeft); } } } else { if (nEqual < 0) { pDesLeft->Nth(iDesLeft - 1, segDes); if (segSrcL.Is(CURVE_ARC)||segDes.Is(CURVE_ARC)) { if (segDes.Intersection(segSrcL, TADSGePoint3d(), TADSGePoint3d()) == 0 || segDes.Intersection(segSrcR, TADSGePoint3d(), TADSGePoint3d()) == 0) { bAsEqual = true; } } if (!bAsEqual) { pair1 = pairPLine(pSrcLeft, pDesLeft); pair2 = pairPLine(pSrcRight, pDesLeft); } } else { pDesRight->Nth(iDesRight - 1, segDes); if (segSrcL.Is(CURVE_ARC)||segDes.Is(CURVE_ARC)) { if (segDes.Intersection(segSrcL, TADSGePoint3d(), TADSGePoint3d()) == 0 || segDes.Intersection(segSrcR, TADSGePoint3d(), TADSGePoint3d()) == 0) { bAsEqual = true; } } if (!bAsEqual) { pair1 = pairPLine(pSrcLeft, pDesRight); pair2 = pairPLine(pSrcRight, pDesRight); } } } } } if (bAsEqual) { if (bStart) { pair1 = pairPLine(pSrcLeft, pDesLeft); pair2 = pairPLine(pSrcRight, pDesRight); } else { pair1 = pairPLine(pSrcLeft, pDesRight); pair2 = pairPLine(pSrcRight, pDesLeft); } } } vPlRef.push_back(pair1); vPlRef.push_back(pair2); return true; } bool TBaseWallIntegrateTool::GetCenterPoly(const TGGePoly2D& pl1, const TGGePoly2D& pl2, TGGePoly2D& plRet) { if (pl1.TotalSegments() == pl2.TotalSegments()) { AcGePoint3d ptMid; plRet.Reset(); for (int i = 0; i < pl1.Length(); i++) { Midpoint(pl1[i], pl2[i], ptMid); plRet.AppendNode(ptMid, pl1.GetBulge(i)); } return plRet.Length() > 0; } return false; } bool TBaseWallIntegrateTool::GetCenterPoly(const TGGeCurveSegment& seg1, const TGGeCurveSegment& seg2, TGGeCurveSegment& segRet) { Midpoint(seg1.StartPoint(), seg2.StartPoint(), segRet.StartPoint()); Midpoint(seg1.EndPoint(), seg2.EndPoint(), segRet.EndPoint()); segRet.SetBulge(seg1.GetBulge()); return true; } AcGePoint3d& TBaseWallIntegrateTool::GetDesPt(const AcGePoint3d& ptGiven, const AcGePoint3d& ptDesc1, const AcGePoint3d& ptDesc2, bool bNearest) { double dDist1 = ptGiven.distanceTo(ptDesc1); double dDist2 = ptGiven.distanceTo(ptDesc2); if (bNearest) return (AcGePoint3d&)(dDist1 - dDist2 <= _DIST_SNAP ? ptDesc1 : ptDesc2); return (AcGePoint3d&)(dDist1 - dDist2 <= _DIST_SNAP ? ptDesc2 : ptDesc1); } bool TBaseWallIntegrateTool::GetLeftPoly2D(TGGeVisibilityPoly2D& pl1, TGGeVisibilityPoly2D& pl2) { if (pl1.TotalSegments() < 1 || pl2.TotalSegments() < 1) return false; const AcGePoint3d& ptS1 = *pl1[0]; const AcGePoint3d& ptS2 = *pl2[0]; TGGeCurveSegment seg; if (pl1.Nth(0, seg) != RTNORM) return false; int iRet = seg.OnWhichSide1(ptS2); if (seg.Is(CURVE_LINE)) { if (iRet == 0) { // pl2在左侧 TGGeVisibilityPoly2D plTmp = pl1; pl1 = pl2; pl2 = plTmp; } } else if (seg.Is(CURVE_ARC)) { if (seg.StartPoint().Distance2d(ptS1) <= _DIST_SNAP) { // 弧线的起点就是多段线起点 if (iRet == 0) { TGGeVisibilityPoly2D plTmp = pl1; pl1 = pl2; pl2 = plTmp; } } else { // 弧线的起点就是多段线终点 if (iRet == 1) { TGGeVisibilityPoly2D plTmp = pl1; pl1 = pl2; pl2 = plTmp; } } } else return false; return true; } bool TBaseWallIntegrateTool::MovePoly2DDesPt(TGGeVisibilityPoly2D& pl, const TADSGePoint3d& ptGiven, bool bStart) { int iLen = pl.TotalSegments(); if (iLen < 1) return false; TGGeCurveSegment seg(0); if (pl.Nth(bStart ? 0 : iLen - 1, seg) != RTNORM) return false; AcGePoint3d& ptMove = *pl[bStart ? 0 : iLen]; if (seg.Is(CURVE_ARC)) { // 弧线修正凸度值 TGGeArc arc = seg.GetArc(); if (fabs(ptGiven.Distance2d(arc.GetCenterPt()) - arc.GetRadius()) <= _DIST_SNAP) { // 点在圆上 // 多段线的有序两个点 const TADSGePoint3d& ptPlTo = bStart ? *pl[1] : *pl[iLen]; const TADSGePoint3d& ptPlFrom = bStart ? *pl[0] : *pl[iLen - 1]; TADSGePoint3d pt; arc.GetStartPoint(pt); const TADSGePoint3d ptCenter = arc.GetCenterPt(); double dAngle = 0.0; AcGeVector3d vt1 = AcGeVector3d::kIdentity; AcGeVector3d vt2 = AcGeVector3d::kIdentity; if (!bStart) { // 修改多段线终点 if (ptPlFrom.Distance2d(pt) <= _DIST_SNAP) { // pl逆时针绘制 vt1 = ptPlFrom - ptCenter; vt2 = ptGiven - ptCenter; } else { // pl顺时针绘制 vt1 = ptGiven - ptCenter; vt2 = ptPlFrom - ptCenter; } dAngle = vt1.angleTo(vt2, AcGeVector3d::kZAxis); } else { // 修改多段线起点 if (ptPlFrom.Distance2d(pt) <= _DIST_SNAP) { // pl逆时针绘制 vt1 = ptGiven - ptCenter; vt2 = ptPlTo - ptCenter; } else { // pl顺时针绘制 vt1 = ptPlTo - ptCenter; vt2 = ptGiven - ptCenter; } dAngle = vt1.angleTo(vt2, AcGeVector3d::kZAxis); } double dBugle = tan(dAngle / 4); // 根据原弧的凸度正负值确定新弧凸度值 int idx = bStart ? 0 : iLen - 1; double dBugleTmp = tan((pl.GetBulge(idx)) / 4); dBugle = dBugleTmp > g_fZero ? fabs(dBugle) : fabs(dBugle) * (-1); dAngle = atan(dBugle) * 4; pl.SetBulge(idx, dAngle); } } ptMove = ptGiven; return true; } // 取得指向poly内部的方向,线和弧不支持圆,pt:起点或终点,dDir:方向弧度 // 返回值:true:成功,false:失败 // 对arBaseWallLines数组以bwLine为基准,逆时针排序 void TBaseWallIntegrateTool::SortBwl(bool bStart,const TBaseWallLine & bwLine,TDPtrList& arBaseWallLines) { if (arBaseWallLines.Length() == 0) { return; } TGGeVisibilityPoly2D vPoly = bwLine.GetLeftLine(); if (vPoly.Length() < 2) { return; } AcGeVector3d vcBase; AcGePoint3d ptInter; TGGeCurveSegment cvSeg; if (bStart) { ptInter = *vPoly[0]; } else { ptInter = *vPoly[vPoly.Length()-1]; } double dDir=0; if(!vPoly.GetIDirection(ptInter, dDir)) { return; } //建立数组 double dParam = 0.0; BaseWallLineParam bwlParam; std::vector vtBwlParams; double dIDir = 0; for (int i = 0;i < arBaseWallLines.Length();i++) { TBaseWallLine bwl = *arBaseWallLines[i]; if (!bwl.GetLeftLine().GetIDirection(ptInter ,dIDir)) { continue; } if (dDir > dIDir) { dIDir += 2.0*PI; } bwlParam.dParam = dIDir; bwlParam.baseWallLine = bwl; vtBwlParams.push_back(bwlParam); } //排序 std::sort(vtBwlParams.begin(),vtBwlParams.end(),GreaterCompare); //调整 arBaseWallLines.Reset(); typedef std::vector::iterator IT; for (IT it = vtBwlParams.begin();it != vtBwlParams.end();it++) { TBaseWallLine *pBwl = new TBaseWallLine(); *pBwl = (*it).baseWallLine; arBaseWallLines.Append(pBwl); } } // 优先级数组 void TBaseWallIntegrateTool::GetStyleKindArray(const TDPtrList& arBaseWallLines, AcDbIntArray& intArray) { int nStyle = 0; for (int i = 0; i < arBaseWallLines.Length(); i++) { nStyle = arBaseWallLines[i].GetWeight(); if (!intArray.contains(nStyle)) { intArray.append(nStyle); } } } // 获得与nThisStyle同优先级的双线数 // 返回值:与nThisStyle同优先级的双线个数 int TBaseWallIntegrateTool::GetStyleCount(int nThisStyle, const TDPtrList& arBaseWallLines) { int nCount = 0; for (int i = 0; i < arBaseWallLines.Length(); i++) { if (arBaseWallLines[i].GetWeight() == nThisStyle) { nCount++; } } return nCount; } // 获得另外一种材质的优先级 // 返回值:与nThisStyle不同材质的双线的优先级 int TBaseWallIntegrateTool::GetAnotherStyle(int nThisStyle, const TDPtrList& arBaseWallLines) { for (int i = 0; i < arBaseWallLines.Length(); i++) { int iWeight = arBaseWallLines[i].GetWeight(); if (iWeight != nThisStyle) { return iWeight; } } return nThisStyle; } // 正或反方向获得同优先级的关联双线 bool TBaseWallIntegrateTool::GetSameStyleLine(int nThisStyle, BOOL bReverse, const TDPtrList &arBaseWallLines, TBaseWallLine& bwl) { bool bRet = false; if (bReverse) { // 反向 for (int i = arBaseWallLines.Length() - 1; i >= 0; i--) { TBaseWallLine wall = arBaseWallLines[i]; if (wall.GetWeight() == nThisStyle) { bwl = wall; bRet = true; break; } } } else { // 正向 for (int i = 0; i < arBaseWallLines.Length(); i++) { TBaseWallLine wall = arBaseWallLines[i]; if (wall.GetWeight() == nThisStyle) { bwl = wall; bRet = true; break; } } } return bRet; } // 双线尾端融合,baseWallThis为实际发生相交的线,arBaseWallLine为关联双线数组,支持多分支 // 多分支常规情况为1种材料;多分支超过2种材质暂不处理; // 2种材料:以双线数多的材质为优先级高,数目相同时,以实际材质优先级为准 // 返回值:TRUE:成功;FALSE:失败 BOOL TBaseWallIntegrateTool::IntegrateAtTail(bool bStart, TBaseWallLine& baseWallThis, const TDPtrList& arBaseWallLine) { TDPtrList arBaseWallLines; arBaseWallLines.copyFrom(arBaseWallLine); int nLength = arBaseWallLines.Length(); if (nLength == 1) { return TBaseWallIntegrateTool::IntegrateAtTail(bStart, baseWallThis, *arBaseWallLines[0]); } else if (nLength < 1) { return FALSE; } // 排序 SortBwl(bStart, baseWallThis, arBaseWallLines); AcDbIntArray intArray; GetStyleKindArray(arBaseWallLines, intArray); int nThisStyle = baseWallThis.GetWeight(); if (!intArray.contains(nThisStyle)) { intArray.append(nThisStyle); } bool bSuccess = false; TBaseWallLine bwlS,bwlE; //正,反方向关联双线 int nKindCount = intArray.length(); if (nKindCount > 2) //超过2种以上的材料,暂不处理 { } else if (nKindCount == 1) //常规情况 { bwlS = *arBaseWallLines[0]; bwlE = *arBaseWallLines[arBaseWallLines.Length()-1]; bSuccess = true; } else //2种材料 { int nThisStyleCount = GetStyleCount(nThisStyle, arBaseWallLines); int nOtherStyleCount = arBaseWallLines.Length()-nThisStyleCount; nThisStyleCount++; //包括自己 BOOL bAdvance = TRUE; if (nThisStyleCount > nOtherStyleCount) //当前优先 { } else if (nThisStyleCount == nOtherStyleCount) { int stOther = GetAnotherStyle(nThisStyle, arBaseWallLines); if (nThisStyle < stOther) { bAdvance = FALSE; } } else { bAdvance = FALSE; } // 确定关联双线 if (bAdvance) //按正或反方向找同优先级双线 { if(GetSameStyleLine(nThisStyle, FALSE, arBaseWallLines, bwlS)) { bSuccess = true; } if(!GetSameStyleLine(nThisStyle, TRUE, arBaseWallLines, bwlE)) { if (bSuccess) { bSuccess = false; } } } else { bwlS = *arBaseWallLines[0]; bwlE = *arBaseWallLines[arBaseWallLines.Length()-1]; bSuccess = true; } } if (!bSuccess) { return FALSE; } TGGeVisibilityPoly2D polyLeft = baseWallThis.GetLeftLine(); TGGeVisibilityPoly2D polyRight = baseWallThis.GetRightLine(); if(bStart) { TADSGePoint3d pt = *polyLeft[0]; //左线融合 TGGeVisibilityPoly2D vPoly = bwlS.GetLeftLine(); if (pt.Distance(*vPoly[0]) < pt.Distance(*vPoly[vPoly.Length()-1]))//连接vPoly起始端 { TBaseWallIntegrateTool::ModifyPoly2D(polyLeft, bwlS.GetRightLine(), bStart); } else { TBaseWallIntegrateTool::ModifyPoly2D(polyLeft, vPoly, bStart); } // 右线融合 vPoly = bwlE.GetLeftLine(); if (pt.Distance(*vPoly[0]) < pt.Distance(*vPoly[vPoly.Length()-1]))//连接vPoly起始端 { TBaseWallIntegrateTool::ModifyPoly2D(polyRight, vPoly, bStart); } else { TBaseWallIntegrateTool::ModifyPoly2D(polyRight, bwlE.GetRightLine(), bStart); } } else { TADSGePoint3d pt = *polyLeft[polyLeft.Length()-1]; //左线融合 TGGeVisibilityPoly2D vPoly = bwlE.GetLeftLine(); if (pt.Distance(*vPoly[0]) < pt.Distance(*vPoly[vPoly.Length()-1]))//连接vPoly起始端 { TBaseWallIntegrateTool::ModifyPoly2D(polyLeft, vPoly, bStart); } else { TBaseWallIntegrateTool::ModifyPoly2D(polyLeft, bwlE.GetRightLine(), bStart); } // 右线融合 vPoly = bwlS.GetLeftLine(); if (pt.Distance(*vPoly[0]) < pt.Distance(*vPoly[vPoly.Length()-1]))//连接vPoly起始端 { TBaseWallIntegrateTool::ModifyPoly2D(polyRight, bwlS.GetRightLine(), bStart); } else { TBaseWallIntegrateTool::ModifyPoly2D(polyRight, vPoly,bStart); } } baseWallThis.SetLeftLine(polyLeft); baseWallThis.SetRightLine(polyRight); return TRUE; } bool TBaseWallIntegrateTool::IsIntegrate(TGGeLine &line1, TGGeLine &line2, double dSkipDistTol, double dTotalWidth) { bool bRet = false; line1.m_nFlag = 1; line2.m_nFlag = 1; AcGeVector3d vt1 = line1.StartPoint() - line1.EndPoint(); AcGeVector3d vt2 = line2.StartPoint() - line2.EndPoint(); if (vt1.isParallelTo(vt2)) // 平行 { TADSGePoint3d ptMid1, ptMid2, ptMid; Midpoint(line1.StartPoint(), line1.EndPoint(), ptMid1); Midpoint(line2.StartPoint(), line2.EndPoint(), ptMid2); ptMid1.Project(&line2,ptMid); double d =ptMid.Distance(ptMid2); double dd = ptMid.Distance(ptMid1); if (ptMid.Distance(ptMid2) < dTotalWidth * 0.5 // 两平行直线,一条直线到另一条直线的垂直投影是否有重合部分 && ptMid.Distance(ptMid1) < dSkipDistTol) // 平行直线间距 { bRet = true; } } else if (line1.Intersection(&line2, TADSGePoint3d()) > 0) // 相交 { bRet = true; } else // 延长线上相交 { if (LineToLineDist(line1, line2) < dSkipDistTol) // 非相交直线的最短距离在误差范围内 { bRet = true; } } return bRet; } // 判断是否是端点融合 // 返回值:0:两端不相交;1:起始端相交;2:终止端相交;3:两端都相交; int TBaseWallIntegrateTool::IsIntegrateAtTail(const TBaseWallLine& baseWallThis, const TBaseWallLine& baseWallThat) { int nRet = 0; TGGeVisibilityPoly2D lPoly = baseWallThis.GetLeftLine(); TGGeVisibilityPoly2D rPoly = baseWallThis.GetRightLine(); TGGeVisibilityPoly2D lPolyThat = baseWallThat.GetLeftLine(); TGGeVisibilityPoly2D rPolyThat = baseWallThat.GetRightLine(); if (lPoly.TotalSegments() != 1 || rPoly.TotalSegments() != 1 || lPolyThat.TotalSegments() != 1 || rPolyThat.TotalSegments() != 1) // 墙线必须为一段线段(直线或弧线) { return nRet; } TGGeLine lineThisS(*(lPoly[0]), *(rPoly[0])); // 由墙线this起点构造直线 TGGeLine lineThisE(*(lPoly[1]), *(rPoly[1])); // 由墙线this终点构造直线 TGGeLine lineThatS(*(lPolyThat[0]), *(rPolyThat[0])); // 由墙线that起点构造直线 TGGeLine lineThatE(*(lPolyThat[1]), *(rPolyThat[1])); // 由墙线that终点构造直线 // 墙体宽度 TADSGePoint3d &ptWallThisLS = *(rPoly[0]), &ptWallThisRS = *(lPoly[0]); // baseWallThis的起点 TADSGePoint3d &ptWallThatLS = *(lPolyThat[0]), &ptWallThatRS = *(rPolyThat[0]); // baseWallThat的起点 double dWallThisWidth = ptWallThisLS.Distance(ptWallThisRS); double dWallThatWidth = ptWallThatLS.Distance(ptWallThatRS); double dSkipDistTol = dWallThisWidth > dWallThatWidth ? dWallThisWidth * 0.5 : dWallThatWidth * 0.5; // 可以融合时的最大误差值 double dTotalWidth = dWallThatWidth + dWallThisWidth; // 墙体baseWallThis的起始端点处是否与墙体baseWallThat的起始端点处能融合 bool bInterSS = IsIntegrate(lineThisS, lineThatS, dSkipDistTol, dTotalWidth); // 墙体baseWallThis的起始端点处是否与墙体baseWallThat的终止端点处能融合 bool bInterSE = IsIntegrate(lineThisS, lineThatE, dSkipDistTol, dTotalWidth); // 墙体baseWallThis的终止端点处是否与墙体baseWallThat的起始端点处能融合 bool bInterES = IsIntegrate(lineThisE, lineThatS, dSkipDistTol, dTotalWidth); // 墙体baseWallThis的终止端点处是否与墙体baseWallThat的终止端点处能融合 bool bInterEE = IsIntegrate(lineThisE, lineThatE, dSkipDistTol, dTotalWidth); if (bInterSS && !bInterEE || bInterSE && !bInterES) // 起始端相交 { nRet = 1; } else if (!bInterSS && bInterEE || !bInterSE && bInterES) // 终止端相交 { nRet = 2; } else if (bInterSS && bInterEE || bInterSE && bInterES) // 两端都相交 { nRet = 3; } return nRet; } // 直线与直线间距算法(无交点):首先,取两直线端点相互投影,当投影点在在直线上时,保留该点与投影点之间的距离; // 其次,分别计算两直线端点间的距离;最后,取上述值中的最小值即为直线间距。 double TBaseWallIntegrateTool::LineToLineDist(const TGGeLine &line1, const TGGeLine &line2) { std::vector vecDist; TADSGePoint3d &ptS1 = line1.StartPoint(), &ptE1 = line1.EndPoint(); TADSGePoint3d &ptS2 = line2.StartPoint(), &ptE2 = line2.EndPoint(); double dLen1 = line1.GetLength(), dLen2 = line2.GetLength(); TADSGePoint3d pt; //投影点 ptS1.Project(&line2, pt); if (fabs(pt.Distance(ptS2) + pt.Distance(ptE2) -dLen2) < g_distZero) // 投影点在直线上 { vecDist.push_back(pt.Distance(ptS1)); } ptE1.Project(&line2, pt); if (fabs(pt.Distance(ptS2) + pt.Distance(ptE2) -dLen2) < g_distZero) // 投影点在直线上 { vecDist.push_back(pt.Distance(ptE1)); } ptS2.Project(&line1, pt); if (fabs(pt.Distance(ptS1) + pt.Distance(ptE1) -dLen1) < g_distZero) // 投影点在直线上 { vecDist.push_back(pt.Distance(ptS2)); } ptE2.Project(&line1, pt); if (fabs(pt.Distance(ptS1) + pt.Distance(ptE1) -dLen1) < g_distZero) // 投影点在直线上 { vecDist.push_back(pt.Distance(ptE2)); } // 直线端点间距 vecDist.push_back(ptS1.Distance(ptS2)); vecDist.push_back(ptS1.Distance(ptE2)); vecDist.push_back(ptE1.Distance(ptS2)); vecDist.push_back(ptE1.Distance(ptE2)); double dDist = 0.0; std::vector::iterator it; it = std::min_element(vecDist.begin(), vecDist.end()); if (it != vecDist.end()) { dDist = *it; } return dDist; } // 直线与弧线间距算法(无交点):1.取直线端点向弧线做投影,当投影点在弧线上时,保留端点到投影点的距离 // 2,取弧线的端点向直线做投影,当投影点在直线上时,保留端点到投影点的距离 3. 取弧线圆心点向直线做投影, // 当投影点在直线上并且圆心点和投影点连线与弧线有交点时,保留交点与投影点的距离 4.计算直线与弧线端点间距 // 5. 取上述值中最小值即为直线与弧线间距 double TBaseWallIntegrateTool::LineToArcDist(const TGGeLine &line, const TGGeArc &arc) { std::vector vecDist; TADSGePoint3d &ptS1 = line.StartPoint(), &ptE1 = line.EndPoint(); TADSGePoint3d pt; //投影点 // line的起点到arc的投影 ptS1.Project(&arc, pt); if (arc.PtOnArc(pt)) { vecDist.push_back(pt.Distance(ptS1)) ; } // line的终点到arc的投影 ptE1.Project(&arc, pt); if (arc.PtOnArc(pt)) { vecDist.push_back(pt.Distance(ptE1)) ; } // 弧的圆心到线的投影 double dLen = line.GetLength(); TADSGePoint3d ptCenter = arc.GetCenterPt(); ptCenter.Project(&line, pt); if (fabs(pt.Distance(ptS1) + pt.Distance(ptE1) -dLen) < g_distZero) // 投影点在直线上 { TGGeLine lineTemp(ptCenter, pt); lineTemp.m_nFlag = 1; if (arc.Intersection(&lineTemp) > 0) { vecDist.push_back(fabs(pt.Distance(ptCenter) - arc.GetRadius())) ; } } // 弧起点 TADSGePoint3d ptTemp; arc.GetStartPoint(ptTemp); ptTemp.Project(&line, pt); if (fabs(pt.Distance(ptS1) + pt.Distance(ptE1) -dLen) < g_distZero) // 投影点在直线上 { vecDist.push_back(ptTemp.Distance(pt)); } // 弧终点 arc.GetEndPoint(ptTemp); ptTemp.Project(&line, pt); if (fabs(pt.Distance(ptS1) + pt.Distance(ptE1) -dLen) < g_distZero) // 投影点在直线上 { vecDist.push_back(ptTemp.Distance(pt)); } // 直线与弧线端点间距 arc.GetStartPoint(ptTemp); vecDist.push_back(ptTemp.Distance(ptS1)); vecDist.push_back(ptTemp.Distance(ptE1)); arc.GetEndPoint(ptTemp); vecDist.push_back(ptTemp.Distance(ptS1)); vecDist.push_back(ptTemp.Distance(ptE1)); double dDist = 0.0; std::vector::iterator it; it = std::min_element(vecDist.begin(), vecDist.end()); if (it != vecDist.end()) { dDist = *it; } return dDist; } // 弧线与弧线间距算法(无交点): 1.弧线端点相互投影,当投影点在弧线上时,保留端点到投影点的距离 // 2. 取弧线的圆心点向另一条弧做投影,当投影点在另一条弧线上并且圆心点和投影点连线与另一条弧 // 线有交点时,保留交点与投影点的距离 3. 计算弧线端点间的距离 4.取上述值中最小值即为弧线与弧线间距 double TBaseWallIntegrateTool::ArcToArcDist(const TGGeArc &arc1, const TGGeArc &arc2) { std::vector vecDist; TADSGePoint3d pt1, pt2; // arc1的端点和圆心到arc2的投影 arc1.GetStartPoint(pt1); pt1.Project(&arc2, pt2); if (arc2.PtOnArc(pt2)) { vecDist.push_back(pt1.Distance(pt2)); } arc1.GetEndPoint(pt1); pt1.Project(&arc2, pt2); if (arc2.PtOnArc(pt2)) { vecDist.push_back(pt1.Distance(pt2)); } pt1 = arc1.GetCenterPt(); pt1.Project(&arc2, pt2); if (arc2.PtOnArc(pt2)) { TGGeLine lineTemp(pt1, pt2); lineTemp.m_nFlag = 1; if (arc1.Intersection(&lineTemp) > 0) { vecDist.push_back(fabs(pt1.Distance(pt2) - arc1.GetRadius())) ; } } // arc2的端点和圆心到arc1的投影 arc2.GetStartPoint(pt1); pt1.Project(&arc1, pt2); if (arc1.PtOnArc(pt2)) { vecDist.push_back(pt1.Distance(pt2)); } arc2.GetEndPoint(pt1); pt1.Project(&arc1, pt2); if (arc1.PtOnArc(pt2)) { vecDist.push_back(pt1.Distance(pt2)); } pt1 = arc2.GetCenterPt(); pt1.Project(&arc1, pt2); if (arc1.PtOnArc(pt2)) { TGGeLine lineTemp(pt1, pt2); lineTemp.m_nFlag = 1; if (arc2.Intersection(&lineTemp) > 0) { vecDist.push_back(fabs(pt1.Distance(pt2) - arc2.GetRadius())) ; } } // 弧线端点间距 arc1.GetStartPoint(pt1); arc2.GetStartPoint(pt2); vecDist.push_back(pt1.Distance(pt2)); arc2.GetEndPoint(pt2); vecDist.push_back(pt1.Distance(pt2)); arc1.GetEndPoint(pt1); vecDist.push_back(pt1.Distance(pt2)); arc2.GetStartPoint(pt2); vecDist.push_back(pt1.Distance(pt2)); double dDist = 0.0; std::vector::iterator it; it = std::min_element(vecDist.begin(), vecDist.end()); if (it != vecDist.end()) { dDist = *it; } return dDist; } //求两个封闭区域的最小间隙 //返回值:true:成功;false:失败 bool TBaseWallIntegrateTool::GetMinGap(const TGGePoly2D& polyFirst, //[in]区域1 const TGGePoly2D& polySecond, //[in]区域2 double& dGap) //[out]最小间隙 { if (polyFirst.GetFlag() != 1 || polySecond.GetFlag() != 1) // 非闭合 { return false; } AcDbCurve *pCurveFirst = polyFirst.AsAcDbCurve(); AcDbCurve *pCurveSecond = polySecond.AsAcDbCurve(); if (pCurveFirst == NULL || pCurveSecond == NULL) { return false; } // 检查是否相交 AcGePoint3dArray ptArray; pCurveFirst->intersectWith(pCurveSecond,AcDb::kOnBothOperands, ptArray); if (ptArray.length() > 0) { dGap = 0.0; return true; } // 检查是否重叠 TADSGePoint3d pt1 = polyFirst[0]; // 任取一点 TADSGePoint3d pt2 = polySecond[0]; if ((pt2 & polyFirst) == PR_INSIDE || (pt1 & polySecond) == PR_INSIDE) { dGap = 0.0; return true; } // TGGePoly2D 不相交不重叠时的间距 int nLineTypeFirst = 0, nLineTypeSecond = 0; TGGeArc arcFirst, arcSecond; TGGeLine lineFirst, lineSecond; std::vector vecDist; for (int i = 0; i < polyFirst.Length(); i++) { nLineTypeFirst = polyFirst.Nth(i,lineFirst, arcFirst); for(int j = 0; j < polySecond.Length(); j++) { nLineTypeSecond = polySecond.Nth(j, lineSecond, arcSecond); if (nLineTypeFirst == LINE_SEGMENT && nLineTypeSecond == LINE_SEGMENT) { vecDist.push_back(LineToLineDist(lineFirst, lineSecond)); } else if (nLineTypeFirst == LINE_SEGMENT && nLineTypeSecond == ARC_SEGMENT) { vecDist.push_back(LineToArcDist(lineFirst, arcSecond)); } else if (nLineTypeFirst == ARC_SEGMENT && nLineTypeSecond == LINE_SEGMENT) { vecDist.push_back(LineToArcDist(lineSecond, arcFirst)); } else if (nLineTypeFirst == ARC_SEGMENT && nLineTypeSecond == ARC_SEGMENT) { vecDist.push_back(ArcToArcDist(arcFirst, arcSecond)); } } } bool nRet = false; std::vector::iterator it; it = std::min_element(vecDist.begin(), vecDist.end()); if (it != vecDist.end()) { dGap = *it; nRet = true; } return nRet; } #endif