#include "StdAfx.h" #include "WallIdentify.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif IMPLEMENT_SERIAL(CWallData, CObject, VERSIONABLE_SCHEMA | 1) IMPLEMENT_DYNAMIC(CWallIdentify, CObject) CWallIdentify::CWallIdentify() { } CWallIdentify::~CWallIdentify() { Release(); } void CWallIdentify::Release() { CWallData* pData; int iSize = m_arpData.length(); for (int i = 0; i < iSize; i++) { pData = m_arpData.at(i); if (NULL != pData) delete pData; } m_arpData.setLogicalLength(0); } BOOL CWallIdentify::DoIdentify(DList &lstSeg) { // 清除墙线数据 Release(); // 初始化识别条件 CSortData::SetTolerence(TOL_DIST, TOL_ANGLE); // 创建墙线数据 CSortLineDataPtrArray arpLines; CSortCircArcDataPtrArray arpCircArcs; OnCreateCurveData(lstSeg, arpLines, arpCircArcs); // 创建直线墙数据 OnCreateLinearWallData(arpLines); // 创建弧线墙数据 OnCreateCircArcWallData(arpCircArcs); return TRUE; } //传入 void CWallIdentify::OnCreateCurveData(DList &lstSeg, CSortLineDataPtrArray& arpLines, CSortCircArcDataPtrArray& arpCircArcs) { int len = lstSeg.Length(); for(int i=0;i= 0) { // 求直线过原点的垂直线 vtDir = arpLines[iPos]->m_ptEnd - arpLines[iPos]->m_ptStart; vtDir.rotateBy(PI / 2.0, AcGeVector3d::kZAxis); line.set(AcGePoint3d::kOrigin, vtDir); // 求直线到原点距离 // ptDist = line.closestPointTo(AcadUtl::GetCenterPoint(arpLines[iPos]->m_ptStart, arpLines[iPos]->m_ptEnd)); ptDist = line.closestPointTo(MidPoint(arpLines[iPos]->m_ptStart, arpLines[iPos]->m_ptEnd)); arpLines[iPos]->m_dDist = ptDist.distanceTo(AcGePoint3d::kOrigin) * (vtDir.isCodirectionalTo(ptDist - AcGePoint3d::kOrigin) ? 1.0 : -1.0); // 取得相同方向的平行线组 iEnd = iPos; while ((iNext = iPos) >= 0 && (--iPos) >= 0 && fabs(arpLines[iPos]->m_dAngle - arpLines[iNext]->m_dAngle) < TOL_ANGLE) { // 求直线到原点距离 ptDist = line.closestPointTo(MidPoint(arpLines[iPos]->m_ptStart, arpLines[iPos]->m_ptEnd)); arpLines[iPos]->m_dDist = ptDist.distanceTo(AcGePoint3d::kOrigin) * (vtDir.isCodirectionalTo(ptDist - AcGePoint3d::kOrigin) ? 1.0 : -1.0); } // 平行线组按距离排序 qsort(arpLines.asArrayPtr() + iNext, iEnd - iPos, sizeof(CSortLineData*), CSortLineData::DistanceCompare); // 求墙线组,合并重合相接的墙线,墙线配对 iPrev = iEnd; while (iPrev > iPos) { // 求墙线组 iEnd = iPrev; // 连接重合相接的墙线 sr remove it 2007-3-23 不用合并相连的墙线 while ((iNext = iPrev) > iPos && (--iPrev) > iPos && (dDist = fabs(arpLines[iPrev]->m_dDist - arpLines[iNext]->m_dDist)) < MAX_WIDTH) { // if (dDist < TOL_DIST && arpLines[iPrev]->GetOverlap(arpLines[iNext]) > - TOL_DIST) // { // arpLines[iPrev]->Connect(arpLines[iNext]); // delete arpLines[iNext]; // arpLines.removeAt(iNext); // iEnd--; // } } // 墙线配对 OnCalcLinePair(arpLines.asArrayPtr() + iNext, iEnd - iPrev); } } // 删除直线数据 iPos = arpLines.length(); while ((--iPos) >= 0) { ASSERT(NULL != arpLines[iPos]); delete arpLines[iPos]; } arpLines.setLogicalLength(0); } void CWallIdentify::OnCalcLinePair(CSortLineData** pDataArray, int iCount) { ASSERT(NULL != pDataArray && iCount > 0); if (iCount == 1) { if (IS_SINGLE) { OnCreateLinePair(pDataArray[0]); } } else if (iCount == 2) { ASSERT(NULL != pDataArray[0] && NULL != pDataArray[1]); double dDist = fabs(pDataArray[0]->m_dDist - pDataArray[1]->m_dDist); double dOverlap = pDataArray[0]->GetOverlap(pDataArray[1]); if ((IS_SINGLE || dDist > MIN_WIDTH) && dDist < MAX_WIDTH && dOverlap > TOL_DIST) { OnCreateLinePair(pDataArray[0], pDataArray[1]); } else if (IS_SINGLE) { OnCreateLinePair(pDataArray[0]); OnCreateLinePair(pDataArray[1]); } } else { double dDist, dOverlap; AcArray arpOverlap; for (int i = 0; i < iCount; i++) { ASSERT(NULL != pDataArray[i]); for (int j = 0; j < iCount; j++) { ASSERT(NULL != pDataArray[j]); if (i == j || pDataArray[j]->m_dwParam == (DWORD)pDataArray[i]) continue; dDist = fabs(pDataArray[i]->m_dDist - pDataArray[j]->m_dDist); dOverlap = pDataArray[i]->GetOverlap(pDataArray[j]); if ((IS_SINGLE || dDist > MIN_WIDTH) && dDist < MAX_WIDTH && dOverlap > TOL_DIST) { pDataArray[j]->m_dParam = dOverlap; arpOverlap.append(pDataArray[j]); } } int iSize = arpOverlap.length(); if (iSize > 0) { qsort(arpOverlap.asArrayPtr(), iSize, sizeof(CSortLineData*), CSortLineData::ParamDecCompare); pDataArray[i]->m_dwParam = (DWORD)arpOverlap[0]; OnCreateLinePair(pDataArray[i], arpOverlap[0]); arpOverlap.setLogicalLength(0); } else if (IS_SINGLE) { OnCreateLinePair(pDataArray[i]); } } } } void CWallIdentify::OnCreateLinePair(CSortLineData* pLine1, CSortLineData* pLine2) { ASSERT(NULL != pLine1); CWallData* pData = new CWallData; if (NULL != pData) { pData->m_cSide1.m_idCurve = pLine1->m_idEnt; pData->m_cSide1.startPoint() = pLine1->m_ptStart; pData->m_cSide1.endPoint() = pLine1->m_ptEnd; if (pLine2 != NULL) { pData->m_cSide2.m_idCurve = pLine2->m_idEnt; pData->m_cSide2.startPoint() = pLine2->m_ptStart; pData->m_cSide2.endPoint() = pLine2->m_ptEnd; } m_arpData.append(pData); } } void CWallIdentify::OnCorrectLinearArcData(CSortCircArcDataPtrArray& arpLinearArcs) { // 圆弧数据排序 int iPos = arpLinearArcs.length(); qsort(arpLinearArcs.asArrayPtr(), iPos, sizeof(CSortCircArcData*), CSortCircArcData::ParamDecCompare); // 求平行始末点连线组,调整圆弧参数 --iPos; double dDist; AcGeLine3d line; AcGeVector3d vtDir; int iEnd, iNext, iPrev; AcGePoint3d ptDist, ptBase; while (iPos >= 0) { // 求过圆心垂直始末点连线的垂线 vtDir = arpLinearArcs[iPos]->m_vtRef; ptBase = arpLinearArcs[iPos]->m_ptCenter; vtDir.rotateBy(arpLinearArcs[iPos]->m_dAngle / 2.0, arpLinearArcs[iPos]->m_vtNormal); line.set(ptBase, vtDir); // 求始末点连线到参考点距离 ptDist = line.closestPointTo(arpLinearArcs[iPos]->m_ptCenter + vtDir * (arpLinearArcs[iPos]->m_dRadius * cos(arpLinearArcs[iPos]->m_dAngle / 2.0))); arpLinearArcs[iPos]->m_dParam = ptDist.distanceTo(ptBase) * (vtDir.isCodirectionalTo(ptDist - ptBase) ? 1.0 : -1.0); // 取得相同方向的平行线组 iEnd = iPos; while ((iNext = iPos) >= 0 && (--iPos) >= 0 && fabs(arpLinearArcs[iPos]->m_dParam - arpLinearArcs[iNext]->m_dParam) < TOL_ANGLE) { // 求始末点连线到参考点距离 ptDist = line.closestPointTo(arpLinearArcs[iPos]->m_ptCenter + vtDir * (arpLinearArcs[iPos]->m_dRadius * cos(arpLinearArcs[iPos]->m_dAngle / 2.0))); arpLinearArcs[iPos]->m_dParam = ptDist.distanceTo(ptBase) * (vtDir.isCodirectionalTo(ptDist - ptBase) ? 1.0 : -1.0); } // 平行线组按距离排序 qsort(arpLinearArcs.asArrayPtr() + iNext, iEnd - iPos, sizeof(CSortCircArcData*), CSortCircArcData::ParamDecCompare); // 调整圆弧参数 iPrev = iEnd; while (iPrev > iPos) { // 求墙线组 iEnd = iPrev; while ((iNext = iPrev) > iPos && (--iPrev) > iPos && (dDist = fabs(arpLinearArcs[iPrev]->m_dParam - arpLinearArcs[iNext]->m_dParam)) < MAX_WIDTH) { } // 调整圆弧参数 //OnCorrectLinearArcPair(arpLines.asArrayPtr() + iNext, iEnd - iPrev); } } } void CWallIdentify::OnCreateCircArcWallData(CSortCircArcDataPtrArray& arpCircArcs) { // 圆和弧数据排序 int iPos = arpCircArcs.length(); qsort(arpCircArcs.asArrayPtr(), iPos, sizeof(CSortCircArcData*), CSortCircArcData::CircArcDataCompare); // 墙线配对,墙线连接 --iPos; double dDist(0); int iEnd, iNext, iLoop; while (iPos >= 0) { iEnd = iPos; iLoop = -1; // 连接重合相接的墙线 sr remove it 2007-3-23 不用合并相连的墙线 while ((iNext = iPos) >= 0 && (--iPos) >= 0 && arpCircArcs[iPos]->m_ptCenter.distanceTo(arpCircArcs[iNext]->m_ptCenter) < TOL_DIST && (dDist = fabs(arpCircArcs[iPos]->m_dRadius - arpCircArcs[iNext]->m_dRadius)) < MAX_WIDTH) { // if (dDist < TOL_DIST) // { // if (iLoop < 0) iLoop = iNext; // if (arpCircArcs[iPos]->GetOverlap(arpCircArcs[iNext]) > -TOL_DIST) // { // arpCircArcs[iPos]->Connect(arpCircArcs[iNext]); // delete arpCircArcs[iNext]; // arpCircArcs.removeAt(iNext); // iEnd--; // iLoop--; // } // } // else // { // // 首尾相连处理 // if (iLoop >= 0 && iNext != iLoop && arpCircArcs[iNext]->GetOverlap(arpCircArcs[iLoop]) > -TOL_DIST) // { // arpCircArcs[iNext]->Connect(arpCircArcs[iLoop]); // delete arpCircArcs[iLoop]; // arpCircArcs.removeAt(iLoop); // iEnd--; // } // iLoop = -1; // } } // 创建墙线对 OnCalcCircArcPair(arpCircArcs.asArrayPtr() + iNext, iEnd - iPos); } // 删除弧线数据 iPos = arpCircArcs.length(); while ((--iPos) >= 0) { ASSERT(NULL != arpCircArcs[iPos]); delete arpCircArcs[iPos]; } arpCircArcs.setLogicalLength(0); } void CWallIdentify::OnCalcCircArcPair(CSortCircArcData** pDataArray, int iCount) { ASSERT(NULL != pDataArray && iCount > 0); if (iCount == 1) { if (IS_SINGLE) { OnCreateCircArcPair(pDataArray[0]); } } else if (iCount == 2) { ASSERT(NULL != pDataArray[0] && NULL != pDataArray[1]); double dDist = fabs(pDataArray[0]->m_dRadius - pDataArray[1]->m_dRadius); double dOverlap = pDataArray[0]->GetOverlap(pDataArray[1]); if ((IS_SINGLE || dDist > MIN_WIDTH) && dDist < MAX_WIDTH && dOverlap > TOL_DIST) { OnCreateCircArcPair(pDataArray[0], pDataArray[1]); } else if (IS_SINGLE) { OnCreateCircArcPair(pDataArray[0]); OnCreateCircArcPair(pDataArray[1]); } } else { double dDist, dOverlap; AcArray arpOverlap; for (int i = 0; i < iCount; i++) { ASSERT(NULL != pDataArray[i]); for (int j = 0; j < iCount; j++) { ASSERT(NULL != pDataArray[j]); if (i == j || pDataArray[j]->m_dwParam == (DWORD)pDataArray[i]) continue; dDist = fabs(pDataArray[j]->m_dRadius - pDataArray[i]->m_dRadius); dOverlap = pDataArray[i]->GetOverlap(pDataArray[j]); if ((IS_SINGLE || dDist > MIN_WIDTH) && dDist < MAX_WIDTH && dOverlap > TOL_DIST) { pDataArray[j]->m_dParam = dOverlap; arpOverlap.append(pDataArray[j]); } } int iSize = arpOverlap.length(); if (iSize > 0) { qsort(arpOverlap.asArrayPtr(), iSize, sizeof(CSortCircArcData*), CSortCircArcData::ParamDecCompare); pDataArray[i]->m_dwParam = (DWORD)arpOverlap[0]; OnCreateCircArcPair(pDataArray[i], arpOverlap[0]); arpOverlap.setLogicalLength(0); } else if (IS_SINGLE) { OnCreateCircArcPair(pDataArray[i]); } } } } void CWallIdentify::OnCreateCircArcPair(CSortCircArcData* pArc1, CSortCircArcData* pArc2) { ASSERT(NULL != pArc1); CWallData* pData = new CWallData; if (NULL != pData) { pData->m_cSide1.m_idCurve = pArc1->m_idEnt; pData->m_cSide1.m_dAngle = pArc1->m_dAngle; pData->m_cSide1.m_vtNormal = pArc1->m_vtNormal; pData->m_cSide1.center() = pArc1->m_ptCenter; pData->m_cSide1.refVec() = pArc1->m_vtRef * pArc1->m_dRadius; if (pArc2 != NULL) { pData->m_cSide2.m_idCurve = pArc2->m_idEnt; pData->m_cSide2.m_dAngle = pArc2->m_dAngle; pData->m_cSide2.m_vtNormal = pArc2->m_vtNormal; pData->m_cSide2.center() = pArc2->m_ptCenter; pData->m_cSide2.refVec() = pArc2->m_vtRef * pArc2->m_dRadius;; } m_arpData.append(pData); } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// extern AcGeTol g_globalTol; //double CSortData::m_dTolAngle(AcGeContext::gTol.equalPoint()); //double CSortData::m_dTolDist(AcGeContext::gTol.equalPoint()); double CSortData::m_dTolAngle(g_globalTol.equalPoint()); double CSortData::m_dTolDist(g_globalTol.equalPoint()); // modify by cq TFS8208 AcGePoint3d CSortData::m_ptGridSize(1000.0, 1000.0, 0.0); void CSortData::SetTolerence(double dDist, double dAngle) { m_dTolDist = dDist; m_dTolAngle = dAngle; } void CSortData::SetGridSize(double dX, double dY, double dZ) { m_ptGridSize.set(dX, dY, dZ); } CSortLineData::CSortLineData(AcGePoint3d ptStart, AcGePoint3d ptEnd) { m_dAngle = AcGeVector3d::kXAxis.angleTo(ptEnd - ptStart, AcGeVector3d::kZAxis); if (m_dAngle > PI - m_dTolAngle) { m_dAngle = fabs(m_dAngle - PI); if (m_dAngle > PI - m_dTolAngle) m_dAngle = fabs(m_dAngle - PI); m_ptStart = ptEnd; m_ptEnd = ptStart; } else { m_ptStart = ptStart; m_ptEnd = ptEnd; } // if (m_dAngle > PI*2.0 - PI / 18000.0) // m_dAngle -= PI*2.0; // // if (m_dAngle > PI - PI / 18000.0) // { // m_dAngle = fabs(m_dAngle - PI); // m_ptStart = ptEnd; // m_ptEnd = ptStart; // } // else // { // m_ptStart = ptStart; // m_ptEnd = ptEnd; // } // m_dAngle = AcGeVector3d::kXAxis.angleTo(pLine->EndPoint()() - pLine->StartPoint()(), AcGeVector3d::kZAxis); } double CSortLineData::GetOverlap(const CSortLineData* pData) { ASSERT(NULL != pData); AcGeLineSeg3d line(m_ptStart, m_ptEnd); double dOverlap = line.closestPointTo(pData->m_ptStart).distanceTo(line.closestPointTo(pData->m_ptEnd)); if (dOverlap > 0.0) return dOverlap; dOverlap = -m_ptStart.distanceTo(pData->m_ptEnd); double dOverlap1 = -m_ptEnd.distanceTo(pData->m_ptStart); return max(dOverlap, dOverlap1); } void CSortLineData::Connect(const CSortLineData* pData) { ASSERT(NULL != pData); AcGeLine3d line(m_ptStart, m_ptEnd); if (line.paramOf(pData->m_ptStart) < line.paramOf(m_ptStart)) m_ptStart = pData->m_ptStart; if (line.paramOf(pData->m_ptEnd) > line.paramOf(m_ptEnd)) m_ptEnd = pData->m_ptEnd; } int CSortLineData::DirectCompare(const void* pElem1, const void* pElem2) { CSortLineData** pLine1 = (CSortLineData**)pElem1; CSortLineData** pLine2 = (CSortLineData**)pElem2; ASSERT(NULL != (*pLine1) && NULL != (*pLine2)); // 按方向角度排序 return ((*pLine1)->m_dAngle < (*pLine2)->m_dAngle ? -1 : 1); } int CSortLineData::DistanceCompare(const void* pElem1, const void* pElem2) { CSortLineData** pLine1 = (CSortLineData**)pElem1; CSortLineData** pLine2 = (CSortLineData**)pElem2; ASSERT(NULL != (*pLine1) && NULL != (*pLine2)); if (fabs((*pLine1)->m_dDist - (*pLine2)->m_dDist) < m_dTolDist) { // 前后相同,按起始点排序 if ((*pLine1)->m_ptStart.x < (*pLine2)->m_ptStart.x) return -1; else if ((*pLine1)->m_ptStart.x > (*pLine2)->m_ptStart.x) return 1; else if ((*pLine1)->m_ptStart.y < (*pLine2)->m_ptStart.y) return -1; else if ((*pLine1)->m_ptStart.y > (*pLine2)->m_ptStart.y) return 1; else if ((*pLine1)->m_ptStart.z < (*pLine2)->m_ptStart.z) return -1; else return 1; } else { // 按前后排序 return ((*pLine1)->m_dDist < (*pLine2)->m_dDist ? -1 : 1); } } int CSortLineData::ParamDecCompare(const void* pElem1, const void* pElem2) { const CSortLineData** pLine1 = (const CSortLineData**)pElem1; const CSortLineData** pLine2 = (const CSortLineData**)pElem2; ASSERT(NULL != (*pLine1) && NULL != (*pLine2)); if (fabs((*pLine1)->m_dParam - (*pLine2)->m_dParam) < 0.00001) { // m_dParam相同,按前后排序 return ((*pLine1)->m_dDist < (*pLine2)->m_dDist ? -1 : 1); } else { // 按m_dParam排序 return (((*pLine1)->m_dParam > (*pLine2)->m_dParam) ? -1 : 1); } } CSortCircArcData::CSortCircArcData(AcGePoint3d ptCen, double dRadius, double dStartAngle, double dEndAngle) { m_ptCenter = ptCen; m_dRadius = dRadius; m_dAngle = dEndAngle - dStartAngle; if(m_dAngle < 0) m_dAngle += PI*2; m_vtNormal = AcGeVector3d::kZAxis; m_vtRef = AcGeVector3d::kXAxis; m_vtRef.rotateBy(dStartAngle, AcGeVector3d::kZAxis); m_vtRef.normalize(); } double CSortCircArcData::GetOverlap(const CSortCircArcData* pData) { // ASSERT(NULL != pData); // // if (m_dAngle > PI * 2.0 - m_dTolAngle) // return pData->m_dAngle * m_dRadius; // if (pData->m_dAngle > PI * 2.0 - m_dTolAngle) // return m_dAngle * m_dRadius; // // double dAngle1 = m_dAngle - m_vtRef.angleTo(pData->m_vtRef, m_vtNormal); // double dAngle2 = (m_dAngle - dAngle1 + pData->m_dAngle) - PI * 2.0; // // return max(dAngle1, dAngle2) * m_dRadius; //2007-4-10更新 ASSERT(NULL != pData); if (m_dAngle > PI * 2.0 - m_dTolAngle) return pData->m_dAngle * m_dRadius; if (pData->m_dAngle > PI * 2.0 - m_dTolAngle) return m_dAngle * m_dRadius; double dAngle1 = m_vtRef.angleTo(pData->m_vtRef, m_vtNormal); double dAngle2 = (dAngle1 + pData->m_dAngle) - PI * 2.0; dAngle1 = m_dAngle - dAngle1; if (pData->m_dAngle < dAngle1) dAngle1 = pData->m_dAngle; if (m_dAngle < dAngle2) dAngle2 = m_dAngle; return max(dAngle1, dAngle2) * m_dRadius; } void CSortCircArcData::Connect(const CSortCircArcData* pData) { ASSERT(NULL != pData); if (m_dAngle > PI * 2.0 - m_dTolAngle) return; if (pData->m_dAngle > PI * 2.0 - m_dTolAngle) { *this = *pData; return; } double dAngle1 = m_dAngle - m_vtRef.angleTo(pData->m_vtRef, m_vtNormal); double dAngle2 = (m_dAngle - dAngle1 + pData->m_dAngle) - PI * 2.0; if (dAngle1 > 0.0 && dAngle2 > 0.0) m_dAngle = PI * 2.0; else if (dAngle1 > dAngle2) { m_dAngle += (pData->m_dAngle - dAngle1); } else { m_vtRef = pData->m_vtRef; m_dAngle += (pData->m_dAngle - dAngle2); } } //int CSortCircArcData::CircArcDataCompare(const void* pElem1, const void* pElem2) //{ // CSortCircArcData** pCircArc1 = (CSortCircArcData**)pElem1; // CSortCircArcData** pCircArc2 = (CSortCircArcData**)pElem2; // // ASSERT(NULL != (*pCircArc1) && NULL != (*pCircArc2)); // // if ((*pCircArc1)->m_ptCenter.distanceTo((*pCircArc2)->m_ptCenter) < m_dTolDist) // { // if (fabs((*pCircArc1)->m_dRadius - (*pCircArc2)->m_dRadius) < m_dTolDist) // { // // 半径相同,按参考轴角度排序 // double dAngle1 = AcGeVector3d::kXAxis.angleTo((*pCircArc1)->m_vtRef, AcGeVector3d::kZAxis); // double dAngle2 = AcGeVector3d::kXAxis.angleTo((*pCircArc2)->m_vtRef, AcGeVector3d::kZAxis); // return (dAngle1 < dAngle2 ? -1 : 1); // } // else // { // // 圆心相同,按半径排序 // return ((*pCircArc1)->m_dRadius < (*pCircArc2)->m_dRadius ? -1 : 1); // } // } // else // { // // 按圆心位置排序 // if ((*pCircArc1)->m_ptCenter.x < (*pCircArc2)->m_ptCenter.x) // return -1; // else if ((*pCircArc1)->m_ptCenter.x > (*pCircArc2)->m_ptCenter.x) // return 1; // else if ((*pCircArc1)->m_ptCenter.y < (*pCircArc2)->m_ptCenter.y) // return -1; // else if ((*pCircArc1)->m_ptCenter.y > (*pCircArc2)->m_ptCenter.y) // return 1; // else if ((*pCircArc1)->m_ptCenter.z < (*pCircArc2)->m_ptCenter.z) // return -1; // else // return 1; // } //} //2007-3-29 王勇光修改 int CSortCircArcData::CircArcDataCompare(const void* pElem1, const void* pElem2) { CSortCircArcData** pCircArc1 = (CSortCircArcData**)pElem1; CSortCircArcData** pCircArc2 = (CSortCircArcData**)pElem2; ASSERT(NULL != (*pCircArc1) && NULL != (*pCircArc2)); // 按圆心位置排序 if (fabs((*pCircArc1)->m_ptCenter.x - (*pCircArc2)->m_ptCenter.x) < m_dTolDist) { if (fabs((*pCircArc1)->m_ptCenter.y - (*pCircArc2)->m_ptCenter.y) < m_dTolDist) { if (fabs((*pCircArc1)->m_ptCenter.z - (*pCircArc2)->m_ptCenter.z) < m_dTolDist) { // 如果圆心相同 if ((*pCircArc1)->m_ptCenter.distanceTo((*pCircArc2)->m_ptCenter) < m_dTolDist) { if (fabs((*pCircArc1)->m_dRadius - (*pCircArc2)->m_dRadius) < m_dTolDist) { // 半径相同,按参考轴角度排序 double dAngle1 = AcGeVector3d::kXAxis.angleTo((*pCircArc1)->m_vtRef, AcGeVector3d::kZAxis); double dAngle2 = AcGeVector3d::kXAxis.angleTo((*pCircArc2)->m_vtRef, AcGeVector3d::kZAxis); return (dAngle1 < dAngle2 ? -1 : 1); } else { // 圆心相同,按半径排序 return ((*pCircArc1)->m_dRadius < (*pCircArc2)->m_dRadius ? -1 : 1); } } else { return 0; } } else { return ((*pCircArc1)->m_ptCenter.z < (*pCircArc2)->m_ptCenter.z ? -1 : 1); } } else { return ((*pCircArc1)->m_ptCenter.y < (*pCircArc2)->m_ptCenter.y ? -1 : 1); } } else { return ((*pCircArc1)->m_ptCenter.x < (*pCircArc2)->m_ptCenter.x ? -1 : 1); } } int CSortCircArcData::ParamDecCompare(const void* pElem1, const void* pElem2) { const CSortCircArcData** pCircArc1 = (const CSortCircArcData**)pElem1; const CSortCircArcData** pCircArc2 = (const CSortCircArcData**)pElem2; ASSERT(NULL != (*pCircArc1) && NULL != (*pCircArc2)); if (fabs((*pCircArc1)->m_dParam - (*pCircArc2)->m_dParam) < 0.00001) { // m_dParam相同,按半径排序 return ((*pCircArc1)->m_dRadius < (*pCircArc2)->m_dRadius ? -1 : 1); } else { // 按m_dParam排序 return (((*pCircArc1)->m_dParam > (*pCircArc2)->m_dParam) ? -1 : 1); } }