786 lines
21 KiB
C++
786 lines
21 KiB
C++
#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<XCurveSegment> &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<XCurveSegment> &lstSeg, CSortLineDataPtrArray& arpLines, CSortCircArcDataPtrArray& arpCircArcs)
|
||
{
|
||
|
||
int len = lstSeg.Length();
|
||
for(int i=0;i<len;i++){
|
||
XCurveSegment seg = *lstSeg[i];
|
||
if(seg.GetLength() < TOL_DIST)
|
||
continue;
|
||
if(seg.Is(CURVE_LINE)){
|
||
AcGePoint3d ptStart = seg.StartPoint();
|
||
AcGePoint3d ptEnd = seg.EndPoint();
|
||
CSortLineData* pLineData = new CSortLineData(ptStart, ptEnd);
|
||
arpLines.append(pLineData);
|
||
}
|
||
else if(seg.Is(CURVE_ARC)){
|
||
XArc arc = seg.GetArc();
|
||
AcGePoint3d ptCen = arc.GetCenterPt();
|
||
CSortCircArcData* pCircArcData = new CSortCircArcData(ptCen, arc.GetRadius(), arc.GetStarAngle(), arc.GetEndAngle());
|
||
arpCircArcs.append(pCircArcData);
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
AcGePoint3d MidPoint(AcGePoint3d startPoint, AcGePoint3d endPoint)
|
||
{
|
||
AcGePoint3d res;
|
||
res.x=(startPoint.x + endPoint.x)/2.0;
|
||
res.y=(startPoint.y + endPoint.y)/2.0;
|
||
res.z=(startPoint.z + endPoint.z)/2.0;
|
||
return res;
|
||
}
|
||
|
||
|
||
void CWallIdentify::OnCreateLinearWallData(CSortLineDataPtrArray& arpLines)
|
||
{
|
||
// 直线数据排序,按方向排序
|
||
int iPos = arpLines.length();
|
||
qsort(arpLines.asArrayPtr(), iPos, sizeof(CSortLineData*), CSortLineData::DirectCompare);
|
||
|
||
// 求平行线组,墙线连接,墙线配对
|
||
--iPos;
|
||
double dDist(0);
|
||
AcGeLine3d line;
|
||
AcGePoint3d ptDist;
|
||
AcGeVector3d vtDir;
|
||
int iEnd, iNext, iPrev;
|
||
while (iPos >= 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<CSortLineData*> 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<CSortCircArcData*> 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);
|
||
}
|
||
}
|
||
|
||
|
||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
||
|
||
|
||
//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);
|
||
}
|
||
}
|
||
|
||
|