3106 lines
64 KiB
C++
3106 lines
64 KiB
C++
//-----------------------------------------------------------------------------+
|
|
// Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd.
|
|
// = FileName : TBPloyLine.cpp
|
|
// = Version : ver2.0
|
|
// = Author : xlc
|
|
// = CreateDate : 2002-09-09
|
|
// = Description: 类的定义
|
|
// = Maintainers:
|
|
//
|
|
//-----------------------------------------------------------------------------+
|
|
#include "StdAfx.h"
|
|
#include "TBPloyLine.h"
|
|
#include <geray3d.h>
|
|
#include "TchGlobalFunc.h"
|
|
#include "TchPrivateGlobalFunc.h"
|
|
|
|
TBPloyLine::TBPloyLine()
|
|
{
|
|
m_bClosed = 0;
|
|
}
|
|
|
|
TBPloyLine::TBPloyLine(const TBPloyLine& bline)
|
|
{
|
|
ReleaseBasLst();
|
|
POSITION pos = bline.m_BNodeList.GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
TBNode* pNode = bline.m_BNodeList.GetNext(pos);
|
|
TBNode* pNodeNew = new TBNode;
|
|
*pNodeNew = *pNode;
|
|
m_BNodeList.AddTail(pNodeNew);
|
|
}
|
|
m_bClosed = bline.m_bClosed;
|
|
}
|
|
|
|
TBPloyLine::~TBPloyLine()
|
|
{
|
|
POSITION pos = m_BNodeList.GetTailPosition();
|
|
while (pos != NULL)
|
|
{
|
|
TBNode* pNode = m_BNodeList.GetPrev(pos);
|
|
if (pNode != NULL)
|
|
{
|
|
delete pNode;
|
|
}
|
|
}
|
|
m_BNodeList.RemoveAll();
|
|
|
|
pos = m_DNodeList.GetTailPosition();
|
|
while (pos != NULL)
|
|
{
|
|
TDNode* pNode = m_DNodeList.GetPrev(pos);
|
|
if (pNode != NULL)
|
|
{
|
|
delete pNode;
|
|
}
|
|
}
|
|
m_DNodeList.RemoveAll();
|
|
}
|
|
|
|
BOOL TBPloyLine::IsClosed() const
|
|
{
|
|
return m_bClosed;
|
|
}
|
|
|
|
void TBPloyLine::ReleaseAll()
|
|
{
|
|
ReleaseBasLst();
|
|
ReleaseDivLst();
|
|
m_bClosed = 0;
|
|
}
|
|
|
|
void TBPloyLine::ReleaseBasLst()
|
|
{
|
|
POSITION pos = m_BNodeList.GetTailPosition();
|
|
while (pos != NULL)
|
|
{
|
|
TBNode* pNode = m_BNodeList.GetPrev(pos);
|
|
if (pNode != NULL)
|
|
{
|
|
delete pNode;
|
|
}
|
|
}
|
|
m_BNodeList.RemoveAll();
|
|
}
|
|
|
|
void TBPloyLine::ReleaseDivLst()
|
|
{
|
|
POSITION pos = m_DNodeList.GetTailPosition();
|
|
while (pos != NULL)
|
|
{
|
|
TDNode* pNode = m_DNodeList.GetPrev(pos);
|
|
if (pNode != NULL)
|
|
{
|
|
delete pNode;
|
|
}
|
|
}
|
|
m_DNodeList.RemoveAll();
|
|
}
|
|
|
|
TBPloyLine& TBPloyLine::operator = (const TBPloyLine& basLine)
|
|
{
|
|
ReleaseBasLst();
|
|
m_bClosed = basLine.m_bClosed;
|
|
POSITION pos = basLine.m_BNodeList.GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
TBNode* pNode = basLine.m_BNodeList.GetNext(pos);
|
|
if (pNode != NULL)
|
|
{
|
|
TBNode* pNodeNew = new TBNode;
|
|
*pNodeNew = *pNode;
|
|
m_BNodeList.AddTail(pNodeNew);
|
|
}
|
|
}
|
|
ReCalcSValue();
|
|
return *this;
|
|
}
|
|
|
|
void TBPloyLine::RmvOverlapPt(double tol)
|
|
{
|
|
if (IsEmpty())
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (GetLength(1) < TOL)
|
|
{
|
|
TBNode* pHead = Head();
|
|
TBNode* pTail = Tail();
|
|
pHead->m_eType = BLINESEG;
|
|
|
|
if (pHead->m_pArc != NULL)
|
|
{
|
|
delete pHead->m_pArc;
|
|
pHead->m_pArc = NULL;
|
|
}
|
|
|
|
POSITION pos = m_BNodeList.GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
POSITION posTemp = pos;
|
|
TBNode* pNode = m_BNodeList.GetNext(pos);
|
|
if (pNode != pHead && pNode != pTail)
|
|
{
|
|
delete pNode;
|
|
m_BNodeList.RemoveAt(posTemp);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
POSITION pos = m_BNodeList.GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
POSITION posThis = pos;
|
|
TBNode* pNode = m_BNodeList.GetNext(pos);
|
|
TBNode* pNodeNext = NULL;
|
|
if (pos != NULL)
|
|
{
|
|
pNodeNext = m_BNodeList.GetAt(pos);
|
|
}
|
|
|
|
if (pNodeNext != NULL && IsEqual(pNode->m_pt,pNodeNext->m_pt,tol))
|
|
{
|
|
if (m_BNodeList.GetCount() > 2)
|
|
{
|
|
m_BNodeList.RemoveAt(posThis);
|
|
delete pNode;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
BOOL TBPloyLine::InsertBLineInto(TBNode* pNode,TBPloyLine* pBLine,BOOL LinkEdgeUnvisible)
|
|
{
|
|
if (pBLine == NULL)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
if (IsEmpty())
|
|
{
|
|
POSITION pos1 = pBLine->m_BNodeList.GetHeadPosition();
|
|
while (pos1 != NULL)
|
|
{
|
|
TBNode* pNode1 = pBLine->m_BNodeList.GetNext(pos1);
|
|
TBNode* pNodeNew = new TBNode(pNode1);
|
|
m_BNodeList.AddTail(pNodeNew);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
if (pNode == NULL)
|
|
{
|
|
pNode = Tail();
|
|
}
|
|
|
|
TBNodeList tempList;
|
|
|
|
BOOL bNextVisible = pNode->m_bVisible;
|
|
pNode->m_bVisible = 0;
|
|
POSITION pos = m_BNodeList.GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
TBNode* pNodeHere = m_BNodeList.GetNext(pos);
|
|
tempList.AddTail(pNodeHere);
|
|
if (pNodeHere == pNode)
|
|
{
|
|
POSITION pos1 = pBLine->m_BNodeList.GetHeadPosition();
|
|
while (pos1 != NULL)
|
|
{
|
|
TBNode* pNode1 = pBLine->m_BNodeList.GetNext(pos1);
|
|
TBNode* pNodeNew = new TBNode(pNode1);
|
|
if (pos1 == NULL && LinkEdgeUnvisible)
|
|
{
|
|
pNodeNew->m_bVisible = 0;
|
|
}
|
|
tempList.AddTail(pNodeNew);
|
|
}
|
|
TBNode* pNodeHereNew = new TBNode(pNodeHere);
|
|
pNodeHereNew->m_bVisible = bNextVisible;
|
|
tempList.AddTail(pNodeHereNew);//多增加一个结点
|
|
}
|
|
}
|
|
m_BNodeList.RemoveAll();
|
|
m_BNodeList.AddTail(&tempList);
|
|
|
|
ClearUp();
|
|
ReCalcSValue();
|
|
return 1;
|
|
}
|
|
|
|
TBNode* TBPloyLine::GetNodeRangedAt(double ds,double deta,BOOL bPercent)
|
|
{
|
|
if (IsEmpty())
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
double tLen = GetLength();
|
|
if (bPercent)
|
|
{
|
|
deta = fabs(tLen * deta);
|
|
}
|
|
|
|
POSITION pos = m_BNodeList.GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
POSITION posTemp = pos;
|
|
TBNode* pNode = m_BNodeList.GetNext(pos);
|
|
if (fabs(pNode->m_s - ds) < deta)
|
|
{
|
|
return pNode;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void TBPloyLine::ResetHead(TBNode* pHead)
|
|
{
|
|
if (!pHead)
|
|
{
|
|
return;
|
|
}
|
|
if (!m_bClosed)
|
|
{
|
|
return;
|
|
}
|
|
if (m_BNodeList.GetCount() == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
TBNode* pNodeH = m_BNodeList.GetHead();
|
|
if (pNodeH == pHead)
|
|
{
|
|
return;
|
|
}
|
|
|
|
TBNodeList list1,list2;
|
|
BOOL bfront = 1;
|
|
POSITION pos = m_BNodeList.GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
TBNode* pNode = m_BNodeList.GetNext(pos);
|
|
if (pNode == pHead)
|
|
{
|
|
bfront = 0;
|
|
}
|
|
if (bfront)
|
|
{
|
|
list1.AddTail(pNode);
|
|
}
|
|
else if (pos != NULL)
|
|
{
|
|
list2.AddTail(pNode);
|
|
}
|
|
}
|
|
TBNode* pTail1 = list1.GetTail();
|
|
TBNode* pNewTail = new TBNode(pTail1->m_eType,0.,pHead->m_pt);
|
|
list1.AddTail(pNewTail);
|
|
m_BNodeList.RemoveAll();
|
|
m_BNodeList.AddTail(&list2);
|
|
m_BNodeList.AddTail(&list1);
|
|
ReCalcSValue();
|
|
}
|
|
|
|
void TBPloyLine::ClearUp(double tol)
|
|
{
|
|
if (IsEmpty())
|
|
{
|
|
return;
|
|
}
|
|
|
|
RmvOverlapPt(tol);
|
|
MergeCoLine(tol);
|
|
}
|
|
|
|
void TBPloyLine::MergeCoArc(double tol)
|
|
{
|
|
if (IsEmpty())
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (GetLength(1) < TOL)
|
|
{
|
|
TBNode* pHead = Head();
|
|
TBNode* pTail = Tail();
|
|
POSITION pos = m_BNodeList.GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
POSITION posTemp = pos;
|
|
TBNode* pNode = m_BNodeList.GetNext(pos);
|
|
if (pNode != pHead && pNode != pTail)
|
|
{
|
|
delete pNode;
|
|
m_BNodeList.RemoveAt(posTemp);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
TBNode* pNodePrev = NULL;
|
|
POSITION pos = m_BNodeList.GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
POSITION posThis = pos;
|
|
TBNode* pNode = m_BNodeList.GetNext(pos);
|
|
TBNode* pNodeNext = NULL;
|
|
if (pos != NULL)
|
|
{
|
|
pNodeNext = m_BNodeList.GetAt(pos);
|
|
}
|
|
|
|
if (pNodePrev != NULL && pNodePrev->m_eType == BARCSEG &&
|
|
pNode->m_eType == BARCSEG && pNodePrev->m_pArc != NULL && pNode->m_pArc != NULL)
|
|
{
|
|
if (IsEqual(pNodePrev->m_pArc->m_centPt,pNode->m_pArc->m_centPt,tol) &&
|
|
(fabs(pNodePrev->m_pArc->m_R-pNode->m_pArc->m_R)<tol) &&
|
|
IsEqualSign(pNodePrev->m_pArc->m_centAngle,pNode->m_pArc->m_centAngle))
|
|
{
|
|
pNodePrev->m_pArc->m_centAngle += pNode->m_pArc->m_centAngle;
|
|
if (pNodeNext != NULL)
|
|
{
|
|
m_BNodeList.RemoveAt(posThis);
|
|
delete pNode;
|
|
pos = m_BNodeList.Find(pNodeNext);
|
|
continue;
|
|
}
|
|
else
|
|
{//末端点
|
|
delete pNode->m_pArc;
|
|
pNode->m_pArc = NULL;
|
|
}
|
|
}
|
|
}
|
|
pNodePrev = pNode;
|
|
}
|
|
if ((m_BNodeList.GetCount() > 2) && IsClosed())//去除首尾处多余的点。
|
|
{
|
|
TBNode* pNode = m_BNodeList.GetHead();
|
|
POSITION pos = m_BNodeList.GetTailPosition();
|
|
TBNode* pTailNode = m_BNodeList.GetPrev(pos);
|
|
TBNode* pNodePrev = m_BNodeList.GetAt(pos);
|
|
|
|
if (pNodePrev->m_eType == BARCSEG && pNode->m_eType == BARCSEG
|
|
&& pNodePrev->m_pArc != NULL && pNode->m_pArc != NULL)
|
|
{
|
|
if (IsEqual(pNodePrev->m_pArc->m_centPt,pNode->m_pArc->m_centPt,tol) &&
|
|
(fabs(pNodePrev->m_pArc->m_R-pNode->m_pArc->m_R)<tol) &&
|
|
IsEqualSign(pNodePrev->m_pArc->m_centAngle,pNode->m_pArc->m_centAngle))
|
|
{
|
|
pNode->m_pt = pNodePrev->m_pt;
|
|
pNode->m_pArc->m_startAngle = pNodePrev->m_pArc->m_startAngle;
|
|
pNode->m_pArc->m_centAngle += pNodePrev->m_pArc->m_centAngle;
|
|
|
|
pNodePrev->m_eType = BLINESEG;
|
|
delete pNodePrev->m_pArc;
|
|
pNodePrev->m_pArc = NULL;
|
|
|
|
m_BNodeList.RemoveTail();
|
|
delete pTailNode;
|
|
}
|
|
}
|
|
}
|
|
|
|
ReCalcSValue();
|
|
}
|
|
|
|
void TBPloyLine::MergeCoLine(double tol)
|
|
{
|
|
if (IsEmpty())
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (GetLength(1) < TOL)
|
|
{
|
|
TBNode* pHead = Head();
|
|
TBNode* pTail = Tail();
|
|
POSITION pos = m_BNodeList.GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
POSITION posTemp = pos;
|
|
TBNode* pNode = m_BNodeList.GetNext(pos);
|
|
if (pNode != pHead && pNode != pTail)
|
|
{
|
|
delete pNode;
|
|
m_BNodeList.RemoveAt(posTemp);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
AcGeTol tol1;
|
|
tol1.setEqualPoint(tol);
|
|
TBNode* pNodePrev = NULL;
|
|
TBNode* pNodeNext = NULL;
|
|
POSITION pos = m_BNodeList.GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
POSITION posTemp = pos;
|
|
TBNode* pNode = m_BNodeList.GetNext(pos);
|
|
if (pos == NULL)
|
|
{
|
|
pNodeNext = NULL;
|
|
}
|
|
else
|
|
{
|
|
pNodeNext = m_BNodeList.GetAt(pos);
|
|
}
|
|
|
|
if (pNodePrev == NULL && pNodeNext != NULL && m_bClosed)
|
|
{//第一接点且封闭
|
|
TBNode* pNodePrevPrev = NULL;
|
|
POSITION pos1 = m_BNodeList.GetTailPosition();
|
|
if (pos1 != NULL)
|
|
{
|
|
pNodePrev = m_BNodeList.GetPrev(pos1);
|
|
}
|
|
if (pos1 != NULL)
|
|
{
|
|
pNodePrevPrev = m_BNodeList.GetPrev(pos1);
|
|
}
|
|
if (pNodePrevPrev != NULL && pNodePrevPrev != pNode)
|
|
{
|
|
AcGeLine3d line(pNodePrevPrev->m_pt,pNode->m_pt);
|
|
if (line.isOn(pNodeNext->m_pt,tol1) == Adesk::kTrue)
|
|
{
|
|
pNode->m_pt = pNodePrevPrev->m_pt;
|
|
delete pNodePrev;
|
|
m_BNodeList.RemoveAt(m_BNodeList.GetTailPosition());
|
|
pNodePrev = NULL;
|
|
pos = m_BNodeList.GetHeadPosition();
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
else if (pNodeNext != NULL && pNodePrev != NULL && pNodePrev->m_eType == BLINESEG && pNode->m_eType == BLINESEG)
|
|
{
|
|
AcGeLine3d line(pNodePrev->m_pt,pNode->m_pt);
|
|
if (line.isOn(pNodeNext->m_pt,tol1) == Adesk::kTrue)
|
|
{
|
|
delete pNode;
|
|
m_BNodeList.RemoveAt(posTemp);
|
|
pos = m_BNodeList.Find(pNodeNext);
|
|
continue;
|
|
}
|
|
}
|
|
pNodePrev = pNode;
|
|
}
|
|
ReCalcSValue();
|
|
}
|
|
|
|
TBPloyLine TBPloyLine::operator + (const TBPloyLine& basLine) const
|
|
{
|
|
if (IsEmpty())
|
|
{
|
|
return basLine;
|
|
}
|
|
if (basLine.IsEmpty())
|
|
{
|
|
return *this;
|
|
}
|
|
|
|
if (m_bClosed || basLine.m_bClosed)
|
|
{
|
|
return *this;
|
|
}
|
|
|
|
TBPloyLine blineThis(*this);
|
|
TBPloyLine blinePara(basLine);
|
|
|
|
TBNode* pHead1 = blineThis.m_BNodeList.GetHead();
|
|
TBNode* pTail1 = blineThis.m_BNodeList.GetTail();
|
|
TBNode* pHead2 = blinePara.m_BNodeList.GetHead();
|
|
TBNode* pTail2 = blinePara.m_BNodeList.GetTail();
|
|
|
|
if (pHead2 == NULL)
|
|
{
|
|
return *this;
|
|
}
|
|
if (pHead1 == NULL)
|
|
{
|
|
return blinePara;
|
|
}
|
|
|
|
if (IsEqual(pTail1->m_pt,pHead2->m_pt,TOL))
|
|
{
|
|
;
|
|
}
|
|
else if (IsEqual(pTail1->m_pt,pTail2->m_pt,TOL))
|
|
{
|
|
blinePara.Reverse();
|
|
}
|
|
else if (IsEqual(pHead1->m_pt,pHead2->m_pt,TOL))
|
|
{
|
|
blineThis.Reverse();
|
|
}
|
|
else if (IsEqual(pHead1->m_pt,pTail2->m_pt,TOL))
|
|
{
|
|
blineThis.Reverse();
|
|
blinePara.Reverse();
|
|
}
|
|
else
|
|
{
|
|
return *this;
|
|
}
|
|
|
|
TBPloyLine BLine;
|
|
POSITION pos = blineThis.m_BNodeList.GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
TBNode* pNode = blineThis.m_BNodeList.GetNext(pos);
|
|
if (pos == NULL)
|
|
{
|
|
break;
|
|
}
|
|
|
|
TBNode* pNodeNew = new TBNode;
|
|
*pNodeNew = *pNode;
|
|
BLine.m_BNodeList.AddTail(pNodeNew);
|
|
}
|
|
|
|
pos = blinePara.m_BNodeList.GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
TBNode* pNode = blinePara.m_BNodeList.GetNext(pos);
|
|
TBNode* pNodeNew = new TBNode;
|
|
*pNodeNew = *pNode;
|
|
BLine.m_BNodeList.AddTail(pNodeNew);
|
|
}
|
|
BLine.ReCalcSValue();
|
|
return BLine;
|
|
}
|
|
|
|
TBPloyLine& TBPloyLine::Reverse()
|
|
{
|
|
if (m_BNodeList.IsEmpty())
|
|
{
|
|
return *this;
|
|
}
|
|
|
|
TBNodeList tempList;
|
|
TBNode *pNodePre, *pNode;
|
|
double totLength;
|
|
POSITION pos = m_BNodeList.GetTailPosition();
|
|
|
|
pNode = m_BNodeList.GetPrev(pos);
|
|
totLength = pNode->m_s;
|
|
|
|
if (pNode->m_pArc != NULL)
|
|
{
|
|
if (pos == NULL)
|
|
{
|
|
delete pNode->m_pArc;
|
|
}
|
|
else if (pNode->m_pArc != m_BNodeList.GetAt(pos)->m_pArc)
|
|
{
|
|
delete pNode->m_pArc;
|
|
}
|
|
|
|
pNode->m_pArc = NULL;
|
|
}
|
|
|
|
for(pos = m_BNodeList.GetTailPosition(); pos; )
|
|
{
|
|
pNode = m_BNodeList.GetPrev(pos);
|
|
pNodePre = NULL;
|
|
if (pos != NULL)
|
|
{
|
|
pNodePre = m_BNodeList.GetAt(pos);
|
|
}
|
|
if (pNodePre != NULL)
|
|
{//不是第一点
|
|
pNode->m_s = totLength-pNode->m_s;
|
|
|
|
if (pNodePre->m_eType == BLINESEG)
|
|
{
|
|
pNode->m_eType = BLINESEG;
|
|
pNode->m_pArc = NULL;
|
|
}
|
|
else
|
|
{
|
|
pNode->m_pArc = pNodePre->m_pArc;
|
|
if (pNode->m_pArc != NULL)
|
|
{
|
|
pNode->m_eType = BARCSEG;
|
|
double startAng = pNode->m_pArc->m_startAngle + pNode->m_pArc->m_centAngle;
|
|
while (startAng >= 2 * PI)
|
|
{
|
|
startAng -= 2 * PI;
|
|
}
|
|
while (startAng < 0)
|
|
{
|
|
startAng += 2 * PI;
|
|
}
|
|
|
|
pNode->m_pArc->m_startAngle = startAng;
|
|
pNode->m_pArc->m_centAngle = -pNode->m_pArc->m_centAngle;
|
|
}
|
|
else
|
|
{
|
|
pNode->m_eType = BLINESEG;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{//原来的第一点
|
|
pNode->m_s = totLength;
|
|
pNode->m_eType = BLINESEG;
|
|
pNode->m_pArc = NULL;
|
|
}
|
|
tempList.AddTail(pNode);
|
|
}
|
|
//在链表中的位置反向
|
|
m_BNodeList.RemoveAll();
|
|
m_BNodeList.AddTail(&tempList);
|
|
tempList.RemoveAll();
|
|
|
|
return *this;
|
|
}
|
|
|
|
BOOL TBPloyLine::CheckClose()
|
|
{
|
|
if (IsEmpty())
|
|
{
|
|
m_bClosed = 0;
|
|
return 0;
|
|
}
|
|
|
|
if (GetLength() < TOL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
TBNode* pStartNode = m_BNodeList.GetHead();
|
|
TBNode* pEndNode = m_BNodeList.GetTail();
|
|
double dist = (pEndNode->m_pt - pStartNode->m_pt).length();
|
|
if (( dist <= TOL) && (pEndNode != pStartNode))
|
|
{
|
|
m_bClosed = 1;
|
|
}
|
|
else
|
|
{
|
|
m_bClosed = 0;
|
|
}
|
|
return m_bClosed;
|
|
}
|
|
|
|
int TBPloyLine::IsWhere(TBPloyLine* pBLine)
|
|
{
|
|
if (pBLine == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
TBPloyLine BLine(*pBLine);
|
|
BLine.LinearizePLine(PI / 36.);
|
|
|
|
int bInternal0 = 1,count = 1,bInternal,HasOnePointIn = 0,HasOnePointOut = 0;
|
|
for(POSITION ps = BLine.m_BNodeList.GetHeadPosition(); ps;)
|
|
{
|
|
AcGePoint3d pt = BLine.m_BNodeList.GetNext(ps)->m_pt;
|
|
bInternal = IsPtInPolygon(pt);
|
|
if (count == 1)
|
|
{
|
|
bInternal0 = bInternal;
|
|
if (bInternal0 == 1)
|
|
{
|
|
HasOnePointIn = 1;
|
|
}
|
|
else if (bInternal0 == 0)
|
|
{
|
|
HasOnePointOut = 1;
|
|
}
|
|
count++;
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
if (bInternal0 == 0 && bInternal == 1 || bInternal0 == 1 && bInternal == 0)
|
|
{
|
|
return 3;//相交
|
|
}
|
|
bInternal0 = bInternal;
|
|
if (bInternal0 == 1)
|
|
{
|
|
HasOnePointIn = 1;
|
|
}
|
|
else if (bInternal0 == 0)
|
|
{
|
|
HasOnePointOut = 1;
|
|
}
|
|
}
|
|
}
|
|
if (HasOnePointOut)
|
|
{//BLine在THIS外部
|
|
return 2;
|
|
}
|
|
else
|
|
{//BLine在THIS内部
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
BOOL TBPloyLine::Create(const TGGePolygonEx& polySrc)
|
|
{
|
|
TGGePolygonEx poly(polySrc);
|
|
int nCount = poly.Length();
|
|
if (nCount < 2)
|
|
{
|
|
return FALSE;
|
|
}
|
|
double SLength = 0.0;
|
|
TBNode* pNodePrevious = NULL;
|
|
AcGePoint3d pt1;
|
|
for(int i = 0; i < nCount; i++)
|
|
{
|
|
pt1 = (*poly[i]).AsAcGePoint3d();
|
|
if (pNodePrevious)
|
|
{
|
|
SLength += pNodePrevious->m_pt.distanceTo(pt1);
|
|
}
|
|
TBNode* pNode = new TBNode(BLINESEG,SLength,pt1);
|
|
|
|
//wlw临时注释,3d炸碎崩
|
|
pNode->m_bVisible = *(poly.GetVisibleFlag()[i]);
|
|
m_BNodeList.AddTail(pNode);
|
|
pNodePrevious = pNode;
|
|
}
|
|
|
|
//封闭最后一点和第一点
|
|
pt1 = (*poly[0]).AsAcGePoint3d();
|
|
SLength += pNodePrevious->m_pt.distanceTo(pt1);
|
|
|
|
TBNode* pNode = new TBNode(BLINESEG,SLength,pt1);
|
|
|
|
pNode->m_bVisible = *(poly.GetVisibleFlag()[nCount - 1]);
|
|
m_BNodeList.AddTail(pNode);
|
|
|
|
m_bClosed = TRUE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL TBPloyLine::Create(const TGGePoly2D& poly)
|
|
{
|
|
//方法2:直接转换(高效率),缺点是不考虑poly的弧度
|
|
int nCount = poly.Length();
|
|
if (nCount < 2)
|
|
{
|
|
return FALSE;
|
|
}
|
|
double SLength = 0.0;
|
|
TBNode* pNodePrevious = NULL;
|
|
|
|
for(int i = 0; i < nCount; i++)
|
|
{
|
|
AcGePoint3d pt1 = poly[i];
|
|
if (pNodePrevious)
|
|
{
|
|
SLength += pNodePrevious->m_pt.distanceTo(pt1);
|
|
}
|
|
|
|
TBNode* pNode = new TBNode(BLINESEG,SLength,pt1);
|
|
m_BNodeList.AddTail(pNode);
|
|
pNodePrevious = pNode;
|
|
}
|
|
|
|
//封闭最后一点和第一点
|
|
if(poly.IsClosed())
|
|
{
|
|
AcGePoint3d pt1 = poly[0];
|
|
SLength += pNodePrevious->m_pt.distanceTo(pt1);
|
|
TBNode* pNode = new TBNode(BLINESEG,SLength,pt1);
|
|
m_BNodeList.AddTail(pNode);
|
|
|
|
m_bClosed = TRUE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//新增函数,支持LINE,PLINE,CIRCLE,TRACE
|
|
BOOL TBPloyLine::Create(const AcDbEntity* pEntity)
|
|
{
|
|
if (pEntity == NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
ReleaseBasLst();
|
|
|
|
double startUCSAng = 0;
|
|
int ret = 1;
|
|
|
|
if(pEntity->isKindOf(AcDbLine::desc()))
|
|
{
|
|
AcDbLine *pLine = AcDbLine::cast(pEntity);
|
|
if (pLine != NULL)
|
|
{
|
|
AcGePoint3d pt1 = pLine->startPoint();
|
|
AcGePoint3d pt2 = pLine->endPoint();
|
|
TBNode* pNode = new TBNode(BLINESEG,0.0,pt1);
|
|
m_BNodeList.AddTail(pNode);
|
|
double len = pt1.distanceTo(pt2);
|
|
pNode = new TBNode(BLINESEG,len,pt2);
|
|
m_BNodeList.AddTail(pNode);
|
|
}
|
|
}
|
|
else if(pEntity->isKindOf(AcDbArc::desc()))
|
|
{
|
|
AcDbArc *pArc = AcDbArc::cast(pEntity);
|
|
if (pArc != NULL)
|
|
{
|
|
AcGePoint3d cent = pArc->center();
|
|
double startAng = pArc->startAngle();
|
|
double endAng = pArc->endAngle();
|
|
//圆心角
|
|
double EntcAng;
|
|
if (endAng >= startAng)
|
|
{
|
|
EntcAng = endAng - startAng;
|
|
}
|
|
else
|
|
{
|
|
EntcAng = 2 * PI + endAng - startAng;
|
|
}
|
|
double radius = pArc->radius();
|
|
TBArc* pArcTemp = new TBArc(cent,radius,startAng,EntcAng);//ECS
|
|
AcGePoint3d ptStart = pArcTemp->GetStartPoint();//ECS
|
|
AcGePoint3d ptEnd = pArcTemp->GetEndPoint();//ECS
|
|
delete pArcTemp;
|
|
ads_point ads_pt1,ads_pt2,ads_pt3;
|
|
ARX2AdsPt(cent,ads_pt1);
|
|
ARX2AdsPt(ptStart,ads_pt2);
|
|
ARX2AdsPt(ptEnd,ads_pt3);
|
|
startAng = acutAngle(ads_pt1,ads_pt2);//UCS
|
|
endAng = acutAngle(ads_pt1,ads_pt3);//UCS
|
|
|
|
TBArc* pBLArc = new TBArc(cent,radius,startAng,EntcAng);
|
|
TBNode* pNode = new TBNode(BARCSEG,0.0,pBLArc->GetStartPoint(),pBLArc);
|
|
m_BNodeList.AddTail(pNode);
|
|
pNode = new TBNode(BARCSEG,pBLArc->Length(),pBLArc->GetEndPoint());
|
|
m_BNodeList.AddTail(pNode);
|
|
}
|
|
}
|
|
else if(pEntity->isKindOf(AcDbCircle::desc()))
|
|
{
|
|
AcDbCircle *pCircle = AcDbCircle::cast(pEntity);
|
|
if (pCircle != NULL)
|
|
{
|
|
//当是圆时,需要指定UCS起始角。
|
|
AcGePoint3d cent = pCircle->center();
|
|
//圆心角
|
|
double EntcAng = 2 * PI;
|
|
m_bClosed = 1;
|
|
TBArc* pBLArc = new TBArc(cent,pCircle->radius(),startUCSAng,EntcAng);
|
|
TBNode* pNode = new TBNode(BARCSEG,0.0,pBLArc->GetStartPoint(),pBLArc);
|
|
m_BNodeList.AddTail(pNode);
|
|
pNode = new TBNode(BARCSEG,pBLArc->Length(),pBLArc->GetEndPoint());
|
|
m_BNodeList.AddTail(pNode);
|
|
}
|
|
}
|
|
else if(pEntity->isKindOf(AcDbTrace::desc()))
|
|
{
|
|
AcDbTrace *pTrace = AcDbTrace::cast(pEntity);
|
|
if (pTrace != NULL)
|
|
{
|
|
AcGePoint3d pt1,pt2,pt3,pt4,ptStart,ptEnd;
|
|
pTrace->getPointAt(0,pt1);
|
|
pTrace->getPointAt(1,pt2);
|
|
pTrace->getPointAt(2,pt3);
|
|
pTrace->getPointAt(3,pt4);
|
|
ptStart.x = (pt1.x + pt2.x) / 2.;
|
|
ptStart.y = (pt1.y + pt2.y) / 2.;
|
|
ptEnd.x = (pt3.x + pt4.x) / 2.;
|
|
ptEnd.y = (pt3.y + pt4.y) / 2.;
|
|
|
|
TBNode* pNode = new TBNode(BLINESEG,0.0,ptStart);
|
|
m_BNodeList.AddTail(pNode);
|
|
double len = ptStart.distanceTo(ptEnd);
|
|
pNode = new TBNode(BLINESEG,len,ptEnd);
|
|
m_BNodeList.AddTail(pNode);
|
|
}
|
|
}
|
|
else if(pEntity->isKindOf(AcDbPolyline::desc()))
|
|
{
|
|
AcDbPolyline *pPoly = AcDbPolyline::cast(pEntity);
|
|
if (pPoly != NULL)
|
|
{
|
|
double SLength = 0.;
|
|
int nVerts = pPoly->numVerts();
|
|
|
|
if (nVerts < 2)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
double Level = pPoly->elevation();
|
|
|
|
TBNode* pNodePrevious = NULL;
|
|
for (int i = 0; i < nVerts; i++)
|
|
{
|
|
AcDbPolyline::SegType eSegType = pPoly->segType(i);
|
|
double Bulge = 0.0;
|
|
if (pPoly->getBulgeAt(i, Bulge) != Acad::eOk)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
AcGePoint2d pt2d;
|
|
if (pPoly->getPointAt(i, pt2d) != Acad::eOk)
|
|
{
|
|
return 0;
|
|
}
|
|
AcGePoint3d pt1, pt2;
|
|
pt1.set(pt2d.x, pt2d.y, Level);
|
|
|
|
if (pNodePrevious)
|
|
{
|
|
if (pNodePrevious->m_pArc)
|
|
{
|
|
SLength += pNodePrevious->m_pArc->m_R * fabs(pNodePrevious->m_pArc->m_centAngle);
|
|
}
|
|
else
|
|
{
|
|
SLength += pNodePrevious->m_pt.distanceTo(pt1);
|
|
}
|
|
}
|
|
|
|
if (eSegType != AcDbPolyline::kArc || fabs(Bulge) < fTOL)
|
|
{
|
|
TBNode* pNode = new TBNode(BLINESEG,SLength,pt1);
|
|
m_BNodeList.AddTail(pNode);
|
|
pNodePrevious = pNode;
|
|
}
|
|
else
|
|
{
|
|
if (i != nVerts - 1)
|
|
{
|
|
if (pPoly->getPointAt(i+1, pt2d) != Acad::eOk)
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (pPoly->getPointAt(0, pt2d) != Acad::eOk)
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
pt2.set(pt2d.x, pt2d.y, Level);
|
|
|
|
double CenterAng = 4 * atan(Bulge);
|
|
double angx, ang1, ang2;
|
|
|
|
angx = AngleToX(pt1, pt2);
|
|
if (Bulge > 0)
|
|
{
|
|
ang1 = angx + (PI - CenterAng) / 2.0;
|
|
ang2 = ang1 + CenterAng;
|
|
}
|
|
else
|
|
{
|
|
ang1 = angx - (PI + CenterAng) / 2.0;
|
|
ang2 = ang1 + CenterAng;
|
|
}
|
|
while (ang1 >= 2 * PI) ang1 -= 2 * PI;
|
|
while (ang1 < 0) ang1 += 2 * PI;
|
|
while (ang2 >= 2 * PI) ang2 -= 2 * PI;
|
|
while (ang2 < 0) ang2 += 2 * PI;
|
|
|
|
AcGePoint3d pt0, pt11, pt22, pt12, pt3, pt13, pt23;
|
|
double angxx, ll = pt1.distanceTo(pt2) / 2.0;
|
|
pt12.x = (pt1.x + pt2.x) / 2.0;
|
|
pt12.y = (pt1.y + pt2.y) / 2.0;
|
|
pt12.z = (pt1.z + pt2.z) / 2.0;
|
|
|
|
if (Bulge>0)
|
|
{
|
|
angxx = angx - PI / 2.0;
|
|
while (angxx < 0)
|
|
{
|
|
angxx += 2 * PI;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
angxx = angx + PI / 2.0;
|
|
while (angxx >= 2 * PI)
|
|
{
|
|
angxx -= 2 * PI;
|
|
}
|
|
}
|
|
pt3 = polar(pt12, angxx, ll*fabs(Bulge));
|
|
|
|
pt13.x = (pt1.x+pt3.x) / 2.0;
|
|
pt13.y = (pt1.y+pt3.y) / 2.0;
|
|
pt13.z = (pt1.z+pt3.z) / 2.0;
|
|
|
|
pt23.x = (pt2.x+pt3.x) / 2.0;
|
|
pt23.y = (pt2.y+pt3.y) / 2.0;
|
|
pt23.z = (pt2.z+pt3.z) / 2.0;
|
|
|
|
angxx = AngleToX(pt1, pt3) + PI / 2.0;
|
|
while (angxx >= 2 * PI)
|
|
{
|
|
angxx -= 2 * PI;
|
|
}
|
|
pt11 = polar(pt13, angxx, ll);
|
|
|
|
angxx = AngleToX(pt3, pt2) + PI / 2.0;
|
|
while (angxx >= 2 * PI)
|
|
{
|
|
angxx -= 2 * PI;
|
|
}
|
|
pt22 = polar(pt23, angxx, ll);
|
|
|
|
ads_point ads_pt1, ads_pt11, ads_pt2, ads_pt22, ads_pt0;
|
|
|
|
ARX2AdsPt(pt13, ads_pt1);
|
|
ARX2AdsPt(pt11, ads_pt11);
|
|
ARX2AdsPt(pt23, ads_pt2);
|
|
ARX2AdsPt(pt22, ads_pt22);
|
|
|
|
if (acdbInters(ads_pt1, ads_pt11, ads_pt2, ads_pt22, FALSE, ads_pt0) == RTNORM)
|
|
{
|
|
Ads2ARXPt(ads_pt0, pt0);
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
ang1 += PI;
|
|
ang2 += PI;
|
|
while (ang1 >= 2 * PI)
|
|
{
|
|
ang1 -= 2 * PI;
|
|
}
|
|
|
|
while (ang2 >= 2 * PI)
|
|
{
|
|
ang2 -= 2 * PI;
|
|
}
|
|
|
|
double radius = pt0.distanceTo(pt1);
|
|
TBArc* pBLArc = new TBArc;
|
|
pBLArc->m_centPt = pt0;
|
|
pBLArc->m_R = radius;
|
|
pBLArc->m_startAngle = ang1;
|
|
pBLArc->m_centAngle = CenterAng;
|
|
pBLArc->m_startPt = pt1;
|
|
pBLArc->m_endPt = pt2;
|
|
|
|
TBNode* pNode = new TBNode(BARCSEG,SLength,pt1,pBLArc);
|
|
m_BNodeList.AddTail(pNode);
|
|
|
|
pNodePrevious = pNode;
|
|
}
|
|
}
|
|
|
|
if (pPoly->isClosed())
|
|
{
|
|
AcGePoint2d pt2d;
|
|
if (pPoly->getPointAt(0, pt2d) != Acad::eOk)
|
|
{
|
|
return 0;
|
|
}
|
|
AcGePoint3d pt1, pt2;
|
|
pt1.set(pt2d.x, pt2d.y, Level);
|
|
|
|
if (pNodePrevious->m_pArc)
|
|
{
|
|
SLength+=pNodePrevious->m_pArc->m_R*fabs(pNodePrevious->m_pArc->m_centAngle);
|
|
}
|
|
else
|
|
{
|
|
SLength+=pNodePrevious->m_pt.distanceTo(pt1);
|
|
}
|
|
|
|
TBNode* pNode = new TBNode(BLINESEG,SLength,pt1);
|
|
m_BNodeList.AddTail(pNode);
|
|
pNodePrevious = pNode;
|
|
}
|
|
}
|
|
}
|
|
else if(pEntity->isKindOf(AcDb2dPolyline::desc()))
|
|
{
|
|
AcDb2dPolyline *pPoly = AcDb2dPolyline::cast(pEntity);
|
|
if(pPoly != NULL)
|
|
{
|
|
AcDbObjectIterator *pVertIter = pPoly->vertexIterator();
|
|
double SLength = 0.;
|
|
AcDbObjectId vertxId;
|
|
AcDb2dVertex *pVertex;
|
|
TBNode* pNodePrevious = NULL;
|
|
AcGePoint3d FirstPt;
|
|
double Level = pPoly->elevation();
|
|
BOOL bLast = 0;
|
|
for (int vertexNumber = 0; !pVertIter->done();vertexNumber++, pVertIter->step())
|
|
{
|
|
vertxId = pVertIter->objectId();
|
|
if (acdbOpenObject(pVertex, vertxId,AcDb::kForRead) != Acad::eOk)
|
|
{
|
|
return 0;
|
|
}
|
|
if (vertexNumber == 0)
|
|
{
|
|
FirstPt = pVertex->position();
|
|
}
|
|
|
|
double Bulge = pVertex->bulge();//凸度
|
|
AcGePoint3d pt1,pt2;
|
|
|
|
pt1 = pVertex->position();//ECS
|
|
pVertex->close();
|
|
pVertIter->step();
|
|
if (!pVertIter->done())
|
|
{//不是最后一点
|
|
AcDbObjectId vertxId2 = pVertIter->objectId();
|
|
AcDb2dVertex *pVertex2 = NULL;
|
|
if (acdbOpenObject(pVertex2, vertxId2,AcDb::kForRead) != Acad::eOk)
|
|
{
|
|
return 0;
|
|
}
|
|
pt2 = pVertex2->position();//ECS
|
|
pVertex2->close();
|
|
}
|
|
else
|
|
{
|
|
bLast = 1;
|
|
pt2 = FirstPt;
|
|
}
|
|
pVertIter->step(true);
|
|
pt1.z = Level;
|
|
pt2.z = Level;
|
|
|
|
if (pNodePrevious)
|
|
{
|
|
if (pNodePrevious->m_pArc)
|
|
{
|
|
SLength += pNodePrevious->m_pArc->m_R * fabs(pNodePrevious->m_pArc->m_centAngle);
|
|
}
|
|
else
|
|
{
|
|
SLength+=pNodePrevious->m_pt.distanceTo(pt1);
|
|
}
|
|
}
|
|
if (bLast && !pPoly->isClosed())
|
|
{
|
|
TBNode* pNode = new TBNode(BLINESEG,SLength,pt1);
|
|
m_BNodeList.AddTail(pNode);
|
|
break;
|
|
}
|
|
if (fabs(Bulge) < fTOL)
|
|
{
|
|
TBNode* pNode = new TBNode(BLINESEG,SLength,pt1);
|
|
m_BNodeList.AddTail(pNode);
|
|
if (bLast)
|
|
{
|
|
SLength += pt2.distanceTo(pt1);
|
|
TBNode* pNode = new TBNode(BLINESEG,SLength,pt2);
|
|
m_BNodeList.AddTail(pNode);
|
|
}
|
|
pNodePrevious = pNode;
|
|
}
|
|
else
|
|
{
|
|
double CenterAng = 4 * atan(Bulge);
|
|
double angx, ang1, ang2;
|
|
|
|
angx = AngleToX(pt1, pt2);
|
|
if (Bulge > 0)
|
|
{
|
|
ang1 = angx + (PI - CenterAng) / 2.0;
|
|
ang2 = ang1 + CenterAng;
|
|
}
|
|
else
|
|
{
|
|
ang1 = angx - (PI + CenterAng) / 2.0;
|
|
ang2 = ang1 + CenterAng;
|
|
}
|
|
while (ang1 >= 2 * PI)
|
|
{
|
|
ang1 -= 2 * PI;
|
|
}
|
|
while (ang1 < 0)
|
|
{
|
|
ang1 += 2 * PI;
|
|
}
|
|
while (ang2 >= 2 * PI)
|
|
{
|
|
ang2 -= 2 * PI;
|
|
}
|
|
while (ang2 < 0)
|
|
{
|
|
ang2 += 2 * PI;
|
|
}
|
|
|
|
AcGePoint3d pt0, pt11, pt22, pt12, pt3, pt13, pt23;
|
|
double angxx, ll = pt1.distanceTo(pt2) / 2.0;
|
|
pt12.x = (pt1.x + pt2.x) / 2.0;
|
|
pt12.y = (pt1.y + pt2.y) / 2.0;
|
|
pt12.z = (pt1.z + pt2.z) / 2.0;
|
|
|
|
if (Bulge > 0)
|
|
{
|
|
angxx = angx - PI / 2.0;
|
|
while (angxx < 0)
|
|
{
|
|
angxx += 2 * PI;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
angxx = angx + PI / 2.0;
|
|
while (angxx >= 2 * PI)
|
|
{
|
|
angxx -= 2 * PI;
|
|
}
|
|
}
|
|
pt3 = polar(pt12, angxx, ll * fabs(Bulge));
|
|
|
|
pt13.x = (pt1.x + pt3.x) / 2.0;
|
|
pt13.y = (pt1.y + pt3.y) / 2.0;
|
|
pt13.z = (pt1.z + pt3.z) / 2.0;
|
|
|
|
pt23.x = (pt2.x + pt3.x) / 2.0;
|
|
pt23.y = (pt2.y + pt3.y) / 2.0;
|
|
pt23.z = (pt2.z + pt3.z) / 2.0;
|
|
angxx = AngleToX(pt1, pt3) + PI / 2.0;
|
|
while (angxx >= 2*PI)
|
|
{
|
|
angxx -= 2 * PI;
|
|
}
|
|
pt11 = polar(pt13, angxx, ll);
|
|
|
|
angxx = AngleToX(pt3, pt2) + PI / 2.0;
|
|
while (angxx >= 2 * PI)
|
|
{
|
|
angxx -= 2 * PI;
|
|
}
|
|
pt22 = polar(pt23, angxx, ll);
|
|
|
|
ads_point ads_pt1, ads_pt11, ads_pt2, ads_pt22, ads_pt0;
|
|
|
|
ARX2AdsPt(pt13, ads_pt1);
|
|
ARX2AdsPt(pt11, ads_pt11);
|
|
ARX2AdsPt(pt23, ads_pt2);
|
|
ARX2AdsPt(pt22, ads_pt22);
|
|
|
|
if (acdbInters(ads_pt1, ads_pt11, ads_pt2, ads_pt22, FALSE, ads_pt0) == RTNORM)
|
|
{
|
|
Ads2ARXPt(ads_pt0, pt0);
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
ang1 += PI;
|
|
ang2 += PI;
|
|
while (ang1 >= 2*PI)
|
|
{
|
|
ang1 -= 2*PI;
|
|
}
|
|
while (ang2 >= 2*PI)
|
|
{
|
|
ang2 -= 2*PI;
|
|
}
|
|
|
|
double radius = pt0.distanceTo(pt1);
|
|
TBArc* pBLArc = new TBArc;
|
|
pBLArc->m_centPt = pt0;
|
|
pBLArc->m_R = radius;
|
|
pBLArc->m_startAngle = ang1;
|
|
pBLArc->m_centAngle = CenterAng;
|
|
pBLArc->m_startPt = pt1;
|
|
pBLArc->m_endPt = pt2;
|
|
|
|
TBNode* pNode = new TBNode(BARCSEG,SLength,pt1,pBLArc);
|
|
m_BNodeList.AddTail(pNode);
|
|
pNodePrevious = pNode;
|
|
}
|
|
}
|
|
if (pPoly->isClosed())
|
|
{
|
|
AcGePoint3d pt1 = FirstPt;
|
|
if (pNodePrevious->m_pArc)
|
|
{
|
|
SLength += pNodePrevious->m_pArc->m_R * fabs(pNodePrevious->m_pArc->m_centAngle);
|
|
}
|
|
else
|
|
{
|
|
SLength += pNodePrevious->m_pt.distanceTo(pt1);
|
|
}
|
|
|
|
TBNode* pNode = new TBNode(BLINESEG,SLength,pt1);
|
|
m_BNodeList.AddTail(pNode);
|
|
pNodePrevious = pNode;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
TBNode* pStartNode = m_BNodeList.GetHead();
|
|
TBNode* pEndNode = m_BNodeList.GetTail();
|
|
double dist = (pEndNode->m_pt - pStartNode->m_pt).length();
|
|
|
|
if (!pEntity->isKindOf(AcDbCircle::desc()))
|
|
{
|
|
if (( dist <= TOL) && (pEndNode != pStartNode))
|
|
{
|
|
m_bClosed = 1;
|
|
}
|
|
else
|
|
{
|
|
m_bClosed = 0;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
BOOL TBPloyLine::Create(AcDbObjectId& objId)
|
|
{
|
|
if (objId == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
double startUCSAng = 0;
|
|
ReleaseBasLst();
|
|
|
|
AcDbEntity* pEntity;
|
|
Acad::ErrorStatus retStat;
|
|
if ((retStat = acdbOpenObject(pEntity, objId, AcDb::kForRead)) != Acad::eOk)
|
|
{
|
|
acutPrintf(_T("acdbOpenEntity failed! retStat:%d"), retStat);
|
|
return 0;
|
|
}
|
|
CString strLineType = pEntity->isA()->dxfName();
|
|
int isParal = IsZParalECSAndUcs(objId);
|
|
if (!isParal && strLineType != _T("LINE"))
|
|
{//判断实体坐标系与用户坐标系的Z轴是否平行
|
|
AfxMessageBox(_T("ECS与UCS的Z轴不平行!"));
|
|
pEntity->close();
|
|
return 0;
|
|
}
|
|
int ret = 1;
|
|
|
|
if (strLineType == _T("LINE"))
|
|
{
|
|
AcDbLine* pLine = (AcDbLine*)(pEntity);
|
|
AcGePoint3d pt1 = pLine->startPoint();
|
|
AcGePoint3d pt2 = pLine->endPoint();
|
|
WCS2UCS(pt1);
|
|
WCS2UCS(pt2);
|
|
TBNode* pNode = new TBNode(BLINESEG,0.0,pt1);
|
|
m_BNodeList.AddTail(pNode);
|
|
double len = pt1.distanceTo(pt2);
|
|
pNode = new TBNode(BLINESEG,len,pt2);
|
|
m_BNodeList.AddTail(pNode);
|
|
}
|
|
else if (strLineType == _T("ARC"))
|
|
{
|
|
AcDbArc* pArc = (AcDbArc*)(pEntity);
|
|
AcGePoint3d cent = pArc->center();
|
|
double startAng = pArc->startAngle();
|
|
double endAng = pArc->endAngle();
|
|
double EntcAng; //圆心角
|
|
if (endAng >= startAng)
|
|
{
|
|
EntcAng = endAng - startAng;
|
|
}
|
|
else
|
|
{
|
|
EntcAng = 2 * PI + endAng - startAng;
|
|
}
|
|
if (isParal == 2)
|
|
{
|
|
EntcAng = -EntcAng;//反向
|
|
}
|
|
double radius = pArc->radius();
|
|
WCS2ECS(cent,objId);//先从WCS到ECS
|
|
TBArc* pArcTemp = new TBArc(cent,radius,startAng,EntcAng);//ECS
|
|
AcGePoint3d ptStart = pArcTemp->GetStartPoint();//ECS
|
|
AcGePoint3d ptEnd = pArcTemp->GetEndPoint();//ECS
|
|
delete pArcTemp;
|
|
ECS2UCS(cent,objId);//UCS
|
|
ECS2UCS(ptStart,objId);//UCS
|
|
ECS2UCS(ptEnd,objId);//UCS
|
|
ads_point ads_pt1,ads_pt2,ads_pt3;
|
|
ARX2AdsPt(cent,ads_pt1);
|
|
ARX2AdsPt(ptStart,ads_pt2);
|
|
ARX2AdsPt(ptEnd,ads_pt3);
|
|
startAng = acutAngle(ads_pt1,ads_pt2);//UCS
|
|
endAng = acutAngle(ads_pt1,ads_pt3);//UCS
|
|
|
|
TBArc* pBLArc = new TBArc(cent,radius,startAng,EntcAng);
|
|
TBNode* pNode = new TBNode(BARCSEG,0.0,pBLArc->GetStartPoint(),pBLArc);
|
|
m_BNodeList.AddTail(pNode);
|
|
pNode = new TBNode(BARCSEG,pBLArc->Length(),pBLArc->GetEndPoint());
|
|
m_BNodeList.AddTail(pNode);
|
|
}
|
|
else if (strLineType == _T("CIRCLE"))
|
|
{//当是圆时,需要指定UCS起始角。
|
|
AcDbCircle* pCircle = (AcDbCircle*)(pEntity);
|
|
AcGePoint3d cent = pCircle->center();
|
|
WCS2UCS(cent);
|
|
double EntcAng = 2 * PI;//圆心角
|
|
m_bClosed = 1;
|
|
TBArc* pBLArc = new TBArc(cent,pCircle->radius(),startUCSAng,EntcAng);
|
|
TBNode* pNode = new TBNode(BARCSEG,0.0,pBLArc->GetStartPoint(),pBLArc);
|
|
m_BNodeList.AddTail(pNode);
|
|
pNode = new TBNode(BARCSEG,pBLArc->Length(),pBLArc->GetEndPoint());
|
|
m_BNodeList.AddTail(pNode);
|
|
}
|
|
else if (strLineType == _T("TRACE"))
|
|
{
|
|
AcDbTrace* pTrace = (AcDbTrace*)(pEntity);
|
|
AcGePoint3d pt1,pt2,pt3,pt4,ptStart,ptEnd;
|
|
pTrace->getPointAt(0,pt1);
|
|
pTrace->getPointAt(1,pt2);
|
|
pTrace->getPointAt(2,pt3);
|
|
pTrace->getPointAt(3,pt4);
|
|
ptStart.x = (pt1.x + pt2.x) / 2.;
|
|
ptStart.y = (pt1.y + pt2.y) / 2.;
|
|
ptEnd.x = (pt3.x + pt4.x) / 2.;
|
|
ptEnd.y = (pt3.y + pt4.y) / 2.;
|
|
|
|
WCS2UCS(ptStart);
|
|
WCS2UCS(ptEnd);
|
|
TBNode* pNode = new TBNode(BLINESEG,0.0,ptStart);
|
|
m_BNodeList.AddTail(pNode);
|
|
double len = ptStart.distanceTo(ptEnd);
|
|
pNode = new TBNode(BLINESEG,len,ptEnd);
|
|
m_BNodeList.AddTail(pNode);
|
|
}
|
|
else if (strLineType == _T("LWPOLYLINE"))
|
|
{
|
|
AcDbPolyline* pPoly = (AcDbPolyline*)(pEntity);
|
|
double SLength = 0.;
|
|
int nVerts = pPoly->numVerts();
|
|
|
|
if (nVerts < 2)
|
|
{
|
|
pEntity->close();
|
|
return 0;
|
|
}
|
|
|
|
double Level = pPoly->elevation();
|
|
|
|
TBNode* pNodePrevious = NULL;
|
|
for (int i = 0; i < nVerts; i++)
|
|
{
|
|
AcDbPolyline::SegType eSegType = pPoly->segType(i);
|
|
double Bulge = 0.0;
|
|
if (pPoly->getBulgeAt(i, Bulge) != Acad::eOk)
|
|
{
|
|
pEntity->close();
|
|
return 0;
|
|
}
|
|
if (isParal == 2)
|
|
{
|
|
Bulge = -Bulge;
|
|
}
|
|
AcGePoint2d pt2d;
|
|
if (pPoly->getPointAt(i, pt2d) != Acad::eOk)
|
|
{
|
|
pEntity->close();
|
|
return 0;
|
|
}
|
|
AcGePoint3d pt1, pt2;
|
|
pt1.set(pt2d.x, pt2d.y, Level);
|
|
ECS2UCS(pt1, objId);//UCS
|
|
|
|
if (pNodePrevious)
|
|
{
|
|
if (pNodePrevious->m_pArc)
|
|
{
|
|
SLength += pNodePrevious->m_pArc->m_R * fabs(pNodePrevious->m_pArc->m_centAngle);
|
|
}
|
|
else
|
|
{
|
|
SLength += pNodePrevious->m_pt.distanceTo(pt1);
|
|
}
|
|
}
|
|
|
|
if (eSegType != AcDbPolyline::kArc || fabs(Bulge) < fTOL)
|
|
{
|
|
TBNode* pNode = new TBNode(BLINESEG,SLength,pt1);
|
|
m_BNodeList.AddTail(pNode);
|
|
pNodePrevious = pNode;
|
|
}
|
|
else
|
|
{
|
|
if (i != nVerts - 1)
|
|
{
|
|
if (pPoly->getPointAt(i + 1, pt2d) != Acad::eOk)
|
|
{
|
|
pEntity->close();
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (pPoly->getPointAt(0, pt2d) != Acad::eOk)
|
|
{
|
|
pEntity->close();
|
|
return 0;
|
|
}
|
|
}
|
|
pt2.set(pt2d.x, pt2d.y, Level);
|
|
ECS2UCS(pt2, objId);//UCS
|
|
|
|
double CenterAng = 4 * atan(Bulge);
|
|
double angx, ang1, ang2;
|
|
|
|
angx=AngleToX(pt1, pt2);
|
|
if (Bulge > 0)
|
|
{
|
|
ang1 = angx + (PI - CenterAng) / 2.0;
|
|
ang2 = ang1 + CenterAng;
|
|
}
|
|
else
|
|
{
|
|
ang1 = angx - (PI + CenterAng) / 2.0;
|
|
ang2 = ang1 + CenterAng;
|
|
}
|
|
while (ang1 >= 2 * PI)
|
|
{
|
|
ang1 -= 2 * PI;
|
|
}
|
|
while (ang1 < 0)
|
|
{
|
|
ang1 += 2 * PI;
|
|
}
|
|
while (ang2 >= 2*PI)
|
|
{
|
|
ang2 -= 2*PI;
|
|
}
|
|
while (ang2 < 0)
|
|
{
|
|
ang2 += 2*PI;
|
|
}
|
|
|
|
AcGePoint3d pt0, pt11, pt22, pt12, pt3, pt13, pt23;
|
|
double angxx, ll = pt1.distanceTo(pt2) / 2.0;
|
|
pt12.x = (pt1.x + pt2.x) / 2.0;
|
|
pt12.y = (pt1.y + pt2.y) / 2.0;
|
|
pt12.z = (pt1.z + pt2.z) / 2.0;
|
|
|
|
if (Bulge > 0)
|
|
{
|
|
angxx= angx - PI / 2.0;
|
|
while (angxx < 0)
|
|
{
|
|
angxx += 2 * PI;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
angxx = angx + PI / 2.0;
|
|
while (angxx >= 2 * PI)
|
|
{
|
|
angxx -= 2 * PI;
|
|
}
|
|
}
|
|
pt3 = polar(pt12, angxx, ll*fabs(Bulge));
|
|
|
|
pt13.x = (pt1.x + pt3.x) / 2.0;
|
|
pt13.y = (pt1.y + pt3.y) / 2.0;
|
|
pt13.z = (pt1.z + pt3.z) / 2.0;
|
|
|
|
pt23.x = (pt2.x + pt3.x) / 2.0;
|
|
pt23.y = (pt2.y + pt3.y) / 2.0;
|
|
pt23.z = (pt2.z + pt3.z) / 2.0;
|
|
|
|
angxx = AngleToX(pt1, pt3) + PI / 2.0;
|
|
while (angxx >= 2*PI)
|
|
{
|
|
angxx -= 2*PI;
|
|
}
|
|
pt11 = polar(pt13, angxx, ll);
|
|
|
|
angxx = AngleToX(pt3, pt2) + PI / 2.0;
|
|
while (angxx >= 2*PI)
|
|
{
|
|
angxx -= 2*PI;
|
|
}
|
|
pt22 = polar(pt23, angxx, ll);
|
|
|
|
ads_point ads_pt1, ads_pt11, ads_pt2, ads_pt22, ads_pt0;
|
|
|
|
ARX2AdsPt(pt13, ads_pt1);
|
|
ARX2AdsPt(pt11, ads_pt11);
|
|
ARX2AdsPt(pt23, ads_pt2);
|
|
ARX2AdsPt(pt22, ads_pt22);
|
|
|
|
if (acdbInters(ads_pt1, ads_pt11, ads_pt2, ads_pt22, FALSE, ads_pt0) == RTNORM)
|
|
{
|
|
Ads2ARXPt(ads_pt0, pt0);
|
|
}
|
|
else
|
|
{
|
|
pEntity->close();
|
|
return 0;
|
|
}
|
|
|
|
ang1 += PI;
|
|
ang2 += PI;
|
|
while (ang1 >= 2*PI)
|
|
{
|
|
ang1 -= 2*PI;
|
|
}
|
|
while (ang2 >= 2*PI)
|
|
{
|
|
ang2 -= 2*PI;
|
|
}
|
|
|
|
double radius = pt0.distanceTo(pt1);
|
|
TBArc* pBLArc = new TBArc;
|
|
pBLArc->m_centPt = pt0;
|
|
pBLArc->m_R = radius;
|
|
pBLArc->m_startAngle = ang1;
|
|
pBLArc->m_centAngle = CenterAng;
|
|
pBLArc->m_startPt = pt1;
|
|
pBLArc->m_endPt = pt2;
|
|
|
|
TBNode* pNode=new TBNode(BARCSEG,SLength,pt1,pBLArc);
|
|
m_BNodeList.AddTail(pNode);
|
|
|
|
pNodePrevious = pNode;
|
|
}
|
|
}
|
|
|
|
if (pPoly->isClosed())
|
|
{
|
|
AcGePoint2d pt2d;
|
|
if (pPoly->getPointAt(0, pt2d) != Acad::eOk)
|
|
{
|
|
pEntity->close();
|
|
return 0;
|
|
}
|
|
AcGePoint3d pt1, pt2;
|
|
pt1.set(pt2d.x, pt2d.y, Level);
|
|
ECS2UCS(pt1, objId);//UCS
|
|
|
|
if (pNodePrevious->m_pArc)
|
|
SLength += pNodePrevious->m_pArc->m_R*fabs(pNodePrevious->m_pArc->m_centAngle);
|
|
else
|
|
SLength += pNodePrevious->m_pt.distanceTo(pt1);
|
|
|
|
TBNode* pNode = new TBNode(BLINESEG,SLength,pt1);
|
|
m_BNodeList.AddTail(pNode);
|
|
pNodePrevious = pNode;
|
|
}
|
|
}
|
|
else if (strLineType == _T("POLYLINE"))
|
|
{
|
|
AcDb2dPolyline* pPoly = (AcDb2dPolyline*)(pEntity);
|
|
AcDbObjectIterator *pVertIter = pPoly->vertexIterator();
|
|
double SLength = 0.;
|
|
AcDbObjectId vertxId;
|
|
AcDb2dVertex *pVertex;
|
|
TBNode* pNodePrevious = NULL;
|
|
AcGePoint3d FirstPt;
|
|
double Level = pPoly->elevation();
|
|
BOOL bLast = 0;
|
|
for (int vertexNumber = 0; !pVertIter->done();vertexNumber++, pVertIter->step())
|
|
{
|
|
vertxId = pVertIter->objectId();
|
|
if (acdbOpenObject(pVertex, vertxId,AcDb::kForRead) != Acad::eOk)
|
|
{
|
|
pEntity->close();
|
|
return 0;
|
|
}
|
|
if (vertexNumber == 0) FirstPt = pVertex->position();
|
|
|
|
double Bulge = pVertex->bulge();//凸度
|
|
if (isParal == 2) Bulge = -Bulge;//UCS与ECS的Z轴反向平行
|
|
AcGePoint3d pt1,pt2;
|
|
|
|
pt1 = pVertex->position();//ECS
|
|
pVertex->close();
|
|
pVertIter->step();
|
|
if (!pVertIter->done())
|
|
{//不是最后一点
|
|
AcDbObjectId vertxId2 = pVertIter->objectId();
|
|
AcDb2dVertex *pVertex2 = NULL;
|
|
if (acdbOpenObject(pVertex2, vertxId2,AcDb::kForRead) != Acad::eOk)
|
|
{
|
|
pEntity->close();
|
|
return 0;
|
|
}
|
|
pt2 = pVertex2->position();//ECS
|
|
pVertex2->close();
|
|
}
|
|
else
|
|
{
|
|
bLast = 1;
|
|
pt2 = FirstPt;
|
|
}
|
|
pVertIter->step(true); //back
|
|
pt1.z = Level;
|
|
pt2.z = Level;
|
|
ECS2UCS(pt1,objId);//UCS
|
|
ECS2UCS(pt2,objId);//UCS
|
|
|
|
if (pNodePrevious)
|
|
{
|
|
if (pNodePrevious->m_pArc)
|
|
SLength += pNodePrevious->m_pArc->m_R*fabs(pNodePrevious->m_pArc->m_centAngle);
|
|
else
|
|
SLength += pNodePrevious->m_pt.distanceTo(pt1);
|
|
}
|
|
if (bLast && !pPoly->isClosed())
|
|
{
|
|
TBNode* pNode = new TBNode(BLINESEG,SLength,pt1);
|
|
m_BNodeList.AddTail(pNode);
|
|
break;
|
|
}
|
|
if (fabs(Bulge)<fTOL)
|
|
{
|
|
TBNode* pNode = new TBNode(BLINESEG,SLength,pt1);
|
|
m_BNodeList.AddTail(pNode);
|
|
if (bLast)
|
|
{
|
|
SLength += pt2.distanceTo(pt1);
|
|
TBNode* pNode = new TBNode(BLINESEG,SLength,pt2);
|
|
m_BNodeList.AddTail(pNode);
|
|
}
|
|
pNodePrevious = pNode;
|
|
}
|
|
else
|
|
{
|
|
double CenterAng = 4*atan(Bulge);
|
|
double angx, ang1, ang2;
|
|
|
|
angx = AngleToX(pt1, pt2);
|
|
if (Bulge>0)
|
|
{
|
|
ang1 = angx+(PI-CenterAng)/2.0;
|
|
ang2 = ang1+CenterAng;
|
|
}
|
|
else
|
|
{
|
|
ang1 = angx-(PI+CenterAng)/2.0;
|
|
ang2 = ang1+CenterAng;
|
|
}
|
|
while (ang1 >= 2*PI) ang1 -= 2*PI;
|
|
while (ang1<0) ang1 += 2*PI;
|
|
while (ang2 >= 2*PI) ang2 -= 2*PI;
|
|
while (ang2<0) ang2 += 2*PI;
|
|
|
|
AcGePoint3d pt0, pt11, pt22, pt12, pt3, pt13, pt23;
|
|
double angxx, ll = pt1.distanceTo(pt2)/2.0;
|
|
pt12.x = (pt1.x+pt2.x)/2.0;
|
|
pt12.y = (pt1.y+pt2.y)/2.0;
|
|
pt12.z = (pt1.z+pt2.z)/2.0;
|
|
|
|
if (Bulge>0)
|
|
{
|
|
angxx = angx-PI/2.0;
|
|
while (angxx<0) angxx += 2*PI;
|
|
}
|
|
else
|
|
{
|
|
angxx = angx+PI/2.0;
|
|
while (angxx >= 2*PI) angxx -= 2*PI;
|
|
}
|
|
pt3 = polar(pt12, angxx, ll*fabs(Bulge));
|
|
|
|
pt13.x = (pt1.x+pt3.x)/2.0;
|
|
pt13.y = (pt1.y+pt3.y)/2.0;
|
|
pt13.z = (pt1.z+pt3.z)/2.0;
|
|
|
|
pt23.x = (pt2.x+pt3.x)/2.0;
|
|
pt23.y = (pt2.y+pt3.y)/2.0;
|
|
pt23.z = (pt2.z+pt3.z)/2.0;
|
|
angxx = AngleToX(pt1, pt3)+PI/2.0;
|
|
while (angxx >= 2*PI) angxx -= 2*PI;
|
|
pt11 = polar(pt13, angxx, ll);
|
|
|
|
angxx = AngleToX(pt3, pt2)+PI/2.0;
|
|
while (angxx >= 2*PI) angxx -= 2*PI;
|
|
pt22 = polar(pt23, angxx, ll);
|
|
|
|
ads_point ads_pt1, ads_pt11, ads_pt2, ads_pt22, ads_pt0;
|
|
|
|
ARX2AdsPt(pt13, ads_pt1);
|
|
ARX2AdsPt(pt11, ads_pt11);
|
|
ARX2AdsPt(pt23, ads_pt2);
|
|
ARX2AdsPt(pt22, ads_pt22);
|
|
|
|
if (acdbInters(ads_pt1, ads_pt11, ads_pt2, ads_pt22, FALSE, ads_pt0) == RTNORM)
|
|
Ads2ARXPt(ads_pt0, pt0);
|
|
else
|
|
{
|
|
pEntity->close();
|
|
return 0;
|
|
}
|
|
|
|
ang1 += PI;
|
|
ang2 += PI;
|
|
while (ang1 >= 2*PI) ang1 -= 2*PI;
|
|
while (ang2 >= 2*PI) ang2 -= 2*PI;
|
|
|
|
double radius = pt0.distanceTo(pt1);
|
|
TBArc* pBLArc = new TBArc;
|
|
pBLArc->m_centPt = pt0;
|
|
pBLArc->m_R = radius;
|
|
pBLArc->m_startAngle = ang1;
|
|
pBLArc->m_centAngle = CenterAng;
|
|
pBLArc->m_startPt = pt1;
|
|
pBLArc->m_endPt = pt2;
|
|
|
|
TBNode* pNode = new TBNode(BARCSEG,SLength,pt1,pBLArc);
|
|
m_BNodeList.AddTail(pNode);
|
|
pNodePrevious = pNode;
|
|
}
|
|
}
|
|
if (pPoly->isClosed())
|
|
{
|
|
AcGePoint3d pt1 = FirstPt;
|
|
ECS2UCS(pt1, objId);//UCS
|
|
|
|
if (pNodePrevious->m_pArc)
|
|
SLength += pNodePrevious->m_pArc->m_R*fabs(pNodePrevious->m_pArc->m_centAngle);
|
|
else
|
|
SLength += pNodePrevious->m_pt.distanceTo(pt1);
|
|
|
|
TBNode* pNode = new TBNode(BLINESEG,SLength,pt1);
|
|
m_BNodeList.AddTail(pNode);
|
|
pNodePrevious = pNode;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pEntity->close();
|
|
return 0;
|
|
}
|
|
|
|
TBNode* pStartNode = m_BNodeList.GetHead();
|
|
TBNode* pEndNode = m_BNodeList.GetTail();
|
|
double dist = (pEndNode->m_pt - pStartNode->m_pt).length();
|
|
if (strLineType != _T("CIRCLE"))
|
|
{
|
|
if (( dist <= TOL) && (pEndNode != pStartNode))
|
|
m_bClosed = 1;
|
|
else m_bClosed = 0;
|
|
}
|
|
pEntity->close();
|
|
return 1;
|
|
}
|
|
|
|
TBNode* TBPloyLine::Head()
|
|
{
|
|
if (m_BNodeList.IsEmpty()) return NULL;
|
|
else return m_BNodeList.GetHead();
|
|
}
|
|
|
|
TBNode* TBPloyLine::Tail()
|
|
{
|
|
if (m_BNodeList.IsEmpty()) return NULL;
|
|
else return m_BNodeList.GetTail();
|
|
}
|
|
|
|
TBNode* TBPloyLine::GetNextNode(const TBNode* pNode)
|
|
{
|
|
POSITION pos = m_BNodeList.GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
TBNode* pNodeCur = m_BNodeList.GetNext(pos);
|
|
if (pNodeCur == pNode)
|
|
{
|
|
if (pos == NULL) return NULL;
|
|
return m_BNodeList.GetAt(pos);
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
TBNode* TBPloyLine::GetPreNode(const TBNode* pNode)
|
|
{
|
|
POSITION pos = m_BNodeList.GetTailPosition();
|
|
while (pos != NULL)
|
|
{
|
|
TBNode* pNodeCur = m_BNodeList.GetPrev(pos);
|
|
if (pNodeCur == pNode)
|
|
{
|
|
if (pos == NULL) return NULL;
|
|
return m_BNodeList.GetAt(pos);
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
BOOL TBPloyLine::GetDNode(double s,TDNode* pDivNode)
|
|
{
|
|
if (m_BNodeList.IsEmpty())
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
double TotaLen = GetLength();
|
|
if (TotaLen < TOL)
|
|
{
|
|
TBNode* pNode = Head();
|
|
if (pNode == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
pDivNode->m_angTng = 0.;
|
|
pDivNode->m_pt = pNode->m_pt;
|
|
pDivNode->m_s = 0.;
|
|
return 1;
|
|
}
|
|
|
|
if (s < -TOL || s - TotaLen > TOL )
|
|
{
|
|
return 0;
|
|
}
|
|
else if ( fabs(TotaLen - s) <= TOL )
|
|
{
|
|
s = TotaLen;
|
|
}
|
|
else if ( fabs(s) <= TOL)
|
|
{
|
|
s = 0.;
|
|
}
|
|
|
|
POSITION pos = m_BNodeList.GetHeadPosition();
|
|
TBNode* pNodePre = NULL;
|
|
while (pos != NULL)
|
|
{
|
|
TBNode* pNode = m_BNodeList.GetNext(pos);
|
|
double len = pNode->m_s;
|
|
|
|
if (((len - s) >= TOL) && pNodePre != NULL)
|
|
{
|
|
//等分点处于两拐点之间
|
|
//pNodePre == NULL则len一定为0
|
|
//从结点pNodePre处的相对S坐标
|
|
double relatedS = s - pNodePre->m_s;
|
|
if (pNodePre->m_eType == BLINESEG)
|
|
{
|
|
double lineSegLen = pNode->m_s - pNodePre->m_s;
|
|
pDivNode->m_angTng = AngleToX(pNodePre->m_pt,pNode->m_pt);
|
|
pDivNode->m_pt.x = pNodePre->m_pt.x + relatedS*cos(pDivNode->m_angTng);
|
|
pDivNode->m_pt.y = pNodePre->m_pt.y + relatedS*sin(pDivNode->m_angTng);
|
|
|
|
pDivNode->m_s = s;
|
|
return 1;
|
|
}
|
|
else if (pNodePre->m_eType == BARCSEG && pNodePre->m_pArc != NULL)
|
|
{
|
|
pDivNode->m_pt = pNodePre->m_pArc->GetPtAtS(relatedS);
|
|
double ang = AngleToX(pNodePre->m_pArc->m_centPt,pDivNode->m_pt);
|
|
if (pNodePre->m_pArc->m_centAngle<0)
|
|
{//顺时针
|
|
pDivNode->m_angTng = ang - PI / 2.;
|
|
while (pDivNode->m_angTng < 0)
|
|
{
|
|
pDivNode->m_angTng += 2*PI;
|
|
}
|
|
while (pDivNode->m_angTng >= 2*PI)
|
|
{
|
|
pDivNode->m_angTng -= 2*PI;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pDivNode->m_angTng = ang + PI / 2.;
|
|
while (pDivNode->m_angTng < 0)
|
|
{
|
|
pDivNode->m_angTng += 2*PI;
|
|
}
|
|
while (pDivNode->m_angTng >= 2*PI)
|
|
{
|
|
pDivNode->m_angTng -= 2*PI;
|
|
}
|
|
}
|
|
pDivNode->m_s = s;
|
|
return 1;
|
|
}
|
|
}
|
|
else if (fabs(s - len) < TOL)
|
|
{
|
|
//等分点处于基线拐点上
|
|
TBNode* pNodeNext = NULL;
|
|
if (pos != NULL)
|
|
{
|
|
pNodeNext = m_BNodeList.GetNext(pos);
|
|
}
|
|
if (pNodePre == NULL)
|
|
{//处于第一点
|
|
if (pNode->m_eType == BLINESEG)
|
|
{
|
|
if (pNodeNext == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
pDivNode->m_angTng = AngleToX(pNode->m_pt,pNodeNext->m_pt);
|
|
pDivNode->m_pt = pNode->m_pt;
|
|
pDivNode->m_s = s;
|
|
}
|
|
else if (pNode->m_eType == BARCSEG && pNode->m_pArc != NULL)
|
|
{
|
|
pDivNode->m_pt = pNode->m_pt;
|
|
double ang = AngleToX(pNode->m_pArc->m_centPt,pDivNode->m_pt);
|
|
if (pNode->m_pArc->m_centAngle < 0)
|
|
{//顺时针
|
|
pDivNode->m_angTng = ang - PI / 2.;
|
|
while (pDivNode->m_angTng < 0)
|
|
{
|
|
pDivNode->m_angTng += 2*PI;
|
|
}
|
|
while (pDivNode->m_angTng >= 2*PI)
|
|
{
|
|
pDivNode->m_angTng -= 2*PI;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pDivNode->m_angTng = ang + PI / 2.;
|
|
while (pDivNode->m_angTng < 0)
|
|
{
|
|
pDivNode->m_angTng += 2*PI;
|
|
}
|
|
while (pDivNode->m_angTng >= 2*PI)
|
|
{
|
|
pDivNode->m_angTng -= 2*PI;
|
|
}
|
|
}
|
|
pDivNode->m_s = s;
|
|
}
|
|
return 1;
|
|
}
|
|
else if (pNodeNext == NULL)
|
|
{//处于最后一个结点上pNodeFirst
|
|
if (pNodePre == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
if (pNodePre->m_eType == BLINESEG)
|
|
{
|
|
pDivNode->m_angTng = AngleToX(pNodePre->m_pt,pNode->m_pt);
|
|
pDivNode->m_pt = pNode->m_pt;
|
|
pDivNode->m_s = s;
|
|
}
|
|
else if (pNodePre->m_eType == BARCSEG)
|
|
{
|
|
pDivNode->m_pt = pNode->m_pt;
|
|
double ang = AngleToX(pNodePre->m_pArc->m_centPt,pDivNode->m_pt);
|
|
if (pNodePre->m_pArc->m_centAngle < 0)
|
|
{//顺时针
|
|
pDivNode->m_angTng = ang - PI / 2.;
|
|
while (pDivNode->m_angTng < 0)
|
|
{
|
|
pDivNode->m_angTng += 2*PI;
|
|
}
|
|
while (pDivNode->m_angTng >= 2*PI)
|
|
{
|
|
pDivNode->m_angTng -= 2*PI;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pDivNode->m_angTng = ang + PI / 2.;
|
|
while (pDivNode->m_angTng < 0)
|
|
{
|
|
pDivNode->m_angTng += 2*PI;
|
|
}
|
|
while (pDivNode->m_angTng >= 2*PI)
|
|
{
|
|
pDivNode->m_angTng -= 2*PI;
|
|
}
|
|
}
|
|
pDivNode->m_s = s;
|
|
}
|
|
return 1;
|
|
}
|
|
else
|
|
{//处于中间结点上
|
|
if (pNode->m_eType == BLINESEG)
|
|
{
|
|
double angIn;
|
|
double angOut = AngleToX(pNode->m_pt,pNodeNext->m_pt);
|
|
if (pNodePre->m_eType == BLINESEG)
|
|
{
|
|
angIn = AngleToX(pNodePre->m_pt,pNode->m_pt);
|
|
}
|
|
else
|
|
{
|
|
angIn = GetActAngOfArcOut(pNodePre);
|
|
}
|
|
|
|
if (fabs(angOut-angIn) <= PI)
|
|
{
|
|
pDivNode->m_angTng = (angOut + angIn) / 2.;
|
|
}
|
|
else
|
|
{
|
|
pDivNode->m_angTng = (angOut + angIn) / 2. + PI;
|
|
}
|
|
while (pDivNode->m_angTng >= 2*PI)
|
|
{
|
|
pDivNode->m_angTng -= 2*PI;
|
|
}
|
|
while (pDivNode->m_angTng < 0)
|
|
{
|
|
pDivNode->m_angTng += 2*PI;
|
|
}
|
|
pDivNode->m_pt = pNode->m_pt;
|
|
|
|
pDivNode->m_s = s;
|
|
return 1;
|
|
}
|
|
else if (pNode->m_eType == BARCSEG && pNode->m_pArc != NULL)
|
|
{
|
|
double angIn;
|
|
double angOut = GetActAngOfArcIn(pNode);
|
|
if (pNodePre->m_eType == BLINESEG)
|
|
{
|
|
AcGePoint3d pPre = pNodePre->m_pt;
|
|
AcGePoint3d pThis = pNode->m_pt;
|
|
UCS2WCS(pPre);
|
|
UCS2WCS(pThis);
|
|
angIn = AngleToX(pNodePre->m_pt,pNode->m_pt);
|
|
}
|
|
else
|
|
{
|
|
angIn = GetActAngOfArcOut(pNodePre);
|
|
}
|
|
if (fabs(angOut - angIn) <= PI)
|
|
{
|
|
pDivNode->m_angTng = (angOut + angIn) / 2.;
|
|
}
|
|
else
|
|
{
|
|
pDivNode->m_angTng = (angOut + angIn) /2. + PI;
|
|
}
|
|
while (pDivNode->m_angTng >= 2*PI)
|
|
{
|
|
pDivNode->m_angTng -= 2*PI;
|
|
}
|
|
while (pDivNode->m_angTng < 0)
|
|
{
|
|
pDivNode->m_angTng += 2*PI;
|
|
}
|
|
pDivNode->m_pt = pNode->m_pt;
|
|
|
|
pDivNode->m_s = s;
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
pNodePre = pNode;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
double TBPloyLine::GetActAngOfArcIn(TBNode* pNode)
|
|
{
|
|
if (pNode == NULL)
|
|
{
|
|
return 0.;
|
|
}
|
|
if (pNode->m_pArc->m_centAngle >= 0)
|
|
{//逆时针
|
|
double ang = pNode->m_pArc->m_startAngle + PI / 2.;
|
|
while (ang >= 2*PI)
|
|
{
|
|
ang -= 2*PI;
|
|
}
|
|
return ang;
|
|
}
|
|
else
|
|
{
|
|
double ang = pNode->m_pArc->m_startAngle - PI / 2.;
|
|
while (ang < 0)
|
|
{
|
|
ang += 2*PI;
|
|
}
|
|
return ang;
|
|
}
|
|
}
|
|
|
|
double TBPloyLine::GetActAngOfArcOut(TBNode* pNode)
|
|
{
|
|
if (pNode == NULL)
|
|
{
|
|
return 0.;
|
|
}
|
|
if (pNode->m_pArc->m_centAngle >= 0)
|
|
{//逆时针
|
|
double ang = pNode->m_pArc->m_startAngle + PI/2. + pNode->m_pArc->m_centAngle;
|
|
while (ang >= 2*PI)
|
|
{
|
|
ang -= 2*PI;
|
|
}
|
|
return ang;
|
|
}
|
|
else
|
|
{
|
|
double ang = pNode->m_pArc->m_startAngle - PI/2. + pNode->m_pArc->m_centAngle;
|
|
while (ang < 0)
|
|
{
|
|
ang += 2*PI;
|
|
}
|
|
return ang;
|
|
}
|
|
}
|
|
|
|
void TBPloyLine::LinearizePLine(double dAng)
|
|
{
|
|
if (IsEmpty())
|
|
{
|
|
return;
|
|
}
|
|
ReleaseDivLst();
|
|
|
|
DivideByAng(dAng);
|
|
ReleaseBasLst();
|
|
|
|
double length = 0.;
|
|
TDNode* pNodePre = NULL;
|
|
for(POSITION pos = m_DNodeList.GetHeadPosition(); pos;)
|
|
{
|
|
TDNode* pNode = m_DNodeList.GetNext(pos);
|
|
if (m_bClosed && pos == NULL)
|
|
{
|
|
pNode = m_DNodeList.GetHead();
|
|
}
|
|
if (pNodePre != NULL)
|
|
{
|
|
length += pNodePre->m_pt.distanceTo(pNode->m_pt);
|
|
}
|
|
|
|
TBNode* pBasNode = new TBNode(BLINESEG,length,pNode->m_pt);
|
|
m_BNodeList.AddTail(pBasNode);
|
|
pNodePre = pNode;
|
|
}
|
|
}
|
|
|
|
void TBPloyLine::LinearizePLine(int nSegs)
|
|
{
|
|
if (IsEmpty()) return;
|
|
|
|
ReleaseDivLst();
|
|
|
|
DivideBySegs(nSegs,0);
|
|
ReleaseBasLst();
|
|
|
|
double length = 0.;
|
|
TDNode* pNodePre = NULL;
|
|
for(POSITION pos = m_DNodeList.GetHeadPosition(); pos;)
|
|
{
|
|
TDNode* pNode = m_DNodeList.GetNext(pos);
|
|
if (m_bClosed && pos == NULL)
|
|
{
|
|
pNode=m_DNodeList.GetHead();
|
|
}
|
|
if (pNodePre != NULL)
|
|
{
|
|
length += pNodePre->m_pt.distanceTo(pNode->m_pt);
|
|
}
|
|
TBNode* pBasNode = new TBNode(BLINESEG,length,pNode->m_pt);
|
|
m_BNodeList.AddTail(pBasNode);
|
|
pNodePre = pNode;
|
|
}
|
|
}
|
|
|
|
void TBPloyLine::DivideByAng(const double detaAng)
|
|
{//按角度,只划分圆弧
|
|
if (IsEmpty())
|
|
{
|
|
return;
|
|
}
|
|
if (detaAng < TOL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
double Z0 = 0;
|
|
|
|
ReleaseDivLst();
|
|
double TotLength = GetLength();
|
|
if (TotLength < TOL)
|
|
{
|
|
int n = m_BNodeList.GetCount();
|
|
double detaZ = 0;
|
|
int i = 0;
|
|
POSITION pos = m_BNodeList.GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
TBNode* pNode = m_BNodeList.GetNext(pos);
|
|
TDNode* pDieNode = new TDNode;
|
|
pDieNode->m_pt = pNode->m_pt;
|
|
pDieNode->m_pt.z = Z0+i*detaZ;
|
|
pDieNode->m_s = 0.;
|
|
pDieNode->m_angTng = 0.;
|
|
m_DNodeList.AddTail(pDieNode);
|
|
i++;
|
|
}
|
|
return;
|
|
}
|
|
|
|
double unitZ = 0;
|
|
POSITION pos = m_BNodeList.GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
TBNode* pNode = m_BNodeList.GetNext(pos);
|
|
POSITION posTemp = pos;
|
|
TBNode* pNodeNext = NULL;
|
|
if (posTemp != NULL)
|
|
{
|
|
pNodeNext = m_BNodeList.GetNext(posTemp);//得到下一结点但不增加pos
|
|
}
|
|
double s = pNode->m_s;//结点S坐标
|
|
if (pNode->m_eType == BLINESEG)
|
|
{//直线
|
|
TDNode* pDieNode = new TDNode;
|
|
if (GetDNode(s,pDieNode))
|
|
{
|
|
m_DNodeList.AddTail(pDieNode);
|
|
pDieNode->m_pt.z = Z0+unitZ*s;
|
|
}
|
|
}
|
|
else
|
|
{//圆弧
|
|
if (pNodeNext != NULL)
|
|
{//不是最后一点
|
|
if (pNode->m_pArc != NULL)
|
|
{
|
|
double s0 = pNode->m_s;
|
|
double len = pNodeNext->m_s - s0; //线段长度
|
|
int nSeg = abs((int)(pNode->m_pArc->m_centAngle / detaAng + 0.5));//等分数
|
|
if (nSeg == 0)
|
|
{
|
|
nSeg = 1;
|
|
}
|
|
double detaS = len / nSeg;
|
|
if (detaS > TOL)
|
|
{//等分
|
|
for (int i = 0; i < nSeg; i++)
|
|
{
|
|
TDNode* pDieNode = new TDNode;
|
|
if (GetDNode(s0 + i * detaS,pDieNode))
|
|
{
|
|
m_DNodeList.AddTail(pDieNode);
|
|
pDieNode->m_pt.z = Z0 + unitZ * (s0 + i * detaS);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{//最后一点
|
|
TDNode* pDieNode = new TDNode;
|
|
if (GetDNode(s,pDieNode))
|
|
{
|
|
m_DNodeList.AddTail(pDieNode);
|
|
pDieNode->m_pt.z = Z0 + unitZ * s;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void TBPloyLine::DivideBySegs(const int nSegs,BOOL flag)
|
|
{
|
|
if (IsEmpty())
|
|
{
|
|
return;
|
|
}
|
|
if (nSegs == 0)
|
|
{
|
|
return;
|
|
}
|
|
double Z0 = 0;
|
|
|
|
ReleaseDivLst();
|
|
|
|
double TotLength = GetLength();
|
|
if (TotLength < TOL)
|
|
{
|
|
TBNode* pHead = Head();
|
|
if (pHead == NULL) return;
|
|
int n = nSegs;
|
|
double detaZ = 0;
|
|
for (int i = 0;i <= n;i++)
|
|
{
|
|
TDNode* pDieNode = new TDNode;
|
|
pDieNode->m_pt = pHead->m_pt;
|
|
pDieNode->m_pt.z = Z0 + i * detaZ;
|
|
pDieNode->m_s = 0.;
|
|
pDieNode->m_angTng = 0.;
|
|
m_DNodeList.AddTail(pDieNode);
|
|
}
|
|
return;
|
|
}
|
|
|
|
double unitZ = 0;
|
|
POSITION pos = m_BNodeList.GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
TBNode* pNode = m_BNodeList.GetNext(pos);
|
|
POSITION posTemp = pos;
|
|
TBNode* pNodeNext = NULL;
|
|
if (posTemp != NULL)
|
|
{
|
|
pNodeNext = m_BNodeList.GetNext(posTemp);//得到下一结点但不增加pos
|
|
}
|
|
double s = pNode->m_s;//结点S坐标
|
|
if (pNode->m_eType == BLINESEG)
|
|
{
|
|
if (flag && pNodeNext != NULL)
|
|
{//不是最后一个结点
|
|
double s0 = pNode->m_s;
|
|
double len = pNodeNext->m_s - s0; //线段长度
|
|
double detaS = len / nSegs;
|
|
if (detaS > TOL)
|
|
{//等分
|
|
for (int i = 0; i < nSegs; i++)
|
|
{
|
|
TDNode* pDieNode = new TDNode;
|
|
if (GetDNode(s0 + i * detaS,pDieNode))
|
|
{
|
|
m_DNodeList.AddTail(pDieNode);
|
|
pDieNode->m_pt.z = Z0 + unitZ * (s0 + i * detaS);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{//不等分直线或pNodeNext == NULL(最后一点)
|
|
TDNode* pDieNode = new TDNode;
|
|
if (GetDNode(s,pDieNode))
|
|
{
|
|
m_DNodeList.AddTail(pDieNode);
|
|
pDieNode->m_pt.z = Z0 + unitZ * s;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{//圆弧
|
|
if (pNodeNext != NULL)
|
|
{//不是最后一点
|
|
double s0 = pNode->m_s;
|
|
double len = pNodeNext->m_s - s0; //线段长度
|
|
double detaS = len / nSegs;
|
|
if (detaS > TOL)
|
|
{//等分
|
|
for (int i = 0;i < nSegs; i++)
|
|
{
|
|
TDNode* pDieNode = new TDNode;
|
|
if (GetDNode(s0 + i * detaS, pDieNode))
|
|
{
|
|
m_DNodeList.AddTail(pDieNode);
|
|
pDieNode->m_pt.z = Z0 + unitZ * (s0 + i * detaS);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{//最后一点
|
|
TDNode* pDieNode = new TDNode;
|
|
if (GetDNode(s,pDieNode))
|
|
{
|
|
m_DNodeList.AddTail(pDieNode);
|
|
pDieNode->m_pt.z = Z0 + unitZ * s;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
double TBPloyLine::GetLength(BOOL bReCalSCoord) const
|
|
{
|
|
if (IsEmpty())
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if (bReCalSCoord)
|
|
{
|
|
const_cast<TBPloyLine*>(this)->ReCalcSValue();
|
|
}
|
|
TBNode* pNode = m_BNodeList.GetTail();
|
|
if (pNode != NULL)
|
|
{
|
|
return pNode->m_s;
|
|
}
|
|
return 0.;
|
|
}
|
|
|
|
TBNode* TBPloyLine::GetMostLeftNode()
|
|
{
|
|
if (IsEmpty())
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
TBNode* temp = m_BNodeList.GetHead();
|
|
double value = temp->m_pt.x;
|
|
POSITION pos = m_BNodeList.GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
double xMin;
|
|
TBNode* pNode = m_BNodeList.GetNext(pos);
|
|
if (pNode->m_eType == BARCSEG && pNode->m_pArc != NULL)
|
|
{
|
|
xMin = pNode->m_pArc->GetMinX();
|
|
}
|
|
else xMin = pNode->m_pt.x;
|
|
if (xMin < value)
|
|
{
|
|
value = xMin;
|
|
temp = pNode;
|
|
}
|
|
}
|
|
return temp;
|
|
}
|
|
|
|
double TBPloyLine::GetMaxX()
|
|
{
|
|
if (IsEmpty())
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
double value = m_BNodeList.GetHead()->m_pt.x;
|
|
POSITION pos = m_BNodeList.GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
TBNode* pNode = m_BNodeList.GetNext(pos);
|
|
if (pNode->m_eType == BLINESEG)
|
|
{
|
|
if (pNode->m_pt.x > value)
|
|
{
|
|
value = pNode->m_pt.x;
|
|
}
|
|
}
|
|
else if (pNode->m_eType == BARCSEG && pNode->m_pArc != NULL)
|
|
{
|
|
double arcMax = pNode->m_pArc->GetMaxX();
|
|
if (arcMax > value)
|
|
{
|
|
value = arcMax;
|
|
}
|
|
}
|
|
}
|
|
return value;
|
|
}
|
|
|
|
double TBPloyLine::GetMinX()
|
|
{
|
|
if (IsEmpty())
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
double value = m_BNodeList.GetHead()->m_pt.x;
|
|
POSITION pos = m_BNodeList.GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
TBNode* pNode = m_BNodeList.GetNext(pos);
|
|
if (pNode->m_eType == BLINESEG)
|
|
{
|
|
if (pNode->m_pt.x < value)
|
|
{
|
|
value = pNode->m_pt.x;
|
|
}
|
|
}
|
|
else if (pNode->m_eType == BARCSEG && pNode->m_pArc != NULL)
|
|
{
|
|
double arcMin = pNode->m_pArc->GetMinX();
|
|
if (arcMin < value)
|
|
{
|
|
value = arcMin;
|
|
}
|
|
}
|
|
}
|
|
return value;
|
|
}
|
|
|
|
double TBPloyLine::GetMinY()
|
|
{
|
|
if (IsEmpty())
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
double value = m_BNodeList.GetHead()->m_pt.y;
|
|
POSITION pos = m_BNodeList.GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
TBNode* pNode = m_BNodeList.GetNext(pos);
|
|
if (pNode->m_eType == BLINESEG)
|
|
{
|
|
if (pNode->m_pt.y < value)
|
|
{
|
|
value = pNode->m_pt.y;
|
|
}
|
|
}
|
|
else if (pNode->m_eType == BARCSEG && pNode->m_pArc != NULL)
|
|
{
|
|
double arcMin = pNode->m_pArc->GetMinY();
|
|
if (arcMin < value)
|
|
{
|
|
value = arcMin;
|
|
}
|
|
}
|
|
}
|
|
return value;
|
|
}
|
|
|
|
double TBPloyLine::GetMaxY()
|
|
{
|
|
if (IsEmpty())
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
double value = m_BNodeList.GetHead()->m_pt.y;
|
|
POSITION pos = m_BNodeList.GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
TBNode* pNode=m_BNodeList.GetNext(pos);
|
|
if (pNode->m_eType == BLINESEG)
|
|
{
|
|
if (pNode->m_pt.y > value)
|
|
{
|
|
value = pNode->m_pt.y;
|
|
}
|
|
}
|
|
else if (pNode->m_eType == BARCSEG && pNode->m_pArc != NULL)
|
|
{
|
|
double arcMax = pNode->m_pArc->GetMaxY();
|
|
if (arcMax > value)
|
|
{
|
|
value = arcMax;
|
|
}
|
|
}
|
|
}
|
|
return value;
|
|
}
|
|
|
|
BOOL TBPloyLine::GetClockwise()
|
|
{
|
|
if (!m_bClosed)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if (GetLength() < TOL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if (isCircle())
|
|
{
|
|
TBNode* pHead = Head();
|
|
if (pHead->m_pArc->m_centAngle > 0)
|
|
{
|
|
return 2;
|
|
}
|
|
else
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
int nNode = 0;
|
|
AcGePoint3d pt0(0,0,0);
|
|
TBNode* pNodePrev = NULL;
|
|
POSITION pos = m_BNodeList.GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
TBNode* pNode = m_BNodeList.GetNext(pos);
|
|
pt0.x += pNode->m_pt.x;
|
|
pt0.y += pNode->m_pt.y;
|
|
pt0.z += pNode->m_pt.z;
|
|
nNode++;
|
|
}
|
|
pt0.x /= nNode;
|
|
pt0.y /= nNode;
|
|
pt0.z /= nNode;
|
|
|
|
double xigmaS = 0.;
|
|
pos = m_BNodeList.GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
TBNode* pNode = m_BNodeList.GetNext(pos);
|
|
if (pNodePrev != NULL)
|
|
{
|
|
AcGePoint3d pt1 = pNodePrev->m_pt;
|
|
AcGePoint3d pt2 = pNode->m_pt;
|
|
double s = 0;
|
|
s = pt0.x * (pt1.y - pt2.y) + pt1.x * (pt2.y - pt0.y) + pt2.x * (pt0.y - pt1.y);
|
|
xigmaS += s;
|
|
}
|
|
pNodePrev = pNode;
|
|
}
|
|
if (xigmaS > fTOL)
|
|
{
|
|
return 2;
|
|
}
|
|
else if (xigmaS < -fTOL)
|
|
{
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
BOOL TBPloyLine::IsEmpty() const
|
|
{
|
|
return m_BNodeList.IsEmpty();
|
|
}
|
|
|
|
BOOL TBPloyLine::IsIntersectWith(double x,AcGePoint3d pt1,AcGePoint3d pt2) const
|
|
{
|
|
if (GetLength() < TOL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
AcGeLineSeg3d line3d1(pt1,pt2);
|
|
POSITION pos = m_BNodeList.GetHeadPosition();
|
|
TBNode* pNodePre = NULL;
|
|
while (pos != NULL)
|
|
{
|
|
TBNode* pNode = m_BNodeList.GetNext(pos);
|
|
if (pNodePre != NULL)
|
|
{
|
|
if ((pNode->m_pt.x < x - fTOL) || (pNodePre->m_pt.x < x - fTOL))
|
|
{
|
|
if (IsEqual(pNode->m_pt,pt1) || IsEqual(pNode->m_pt,pt2) ||
|
|
IsEqual(pNodePre->m_pt,pt1) || IsEqual(pNodePre->m_pt,pt2))
|
|
{
|
|
pNodePre = pNode;
|
|
continue;
|
|
}
|
|
AcGeLineSeg3d line3d2(pNodePre->m_pt,pNode->m_pt);
|
|
AcGePoint3d secPt;
|
|
if (line3d1.intersectWith(line3d2,secPt) == Adesk::kTrue)
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
pNodePre = pNode;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
BOOL TBPloyLine::IsPtInPolygon(AcGePoint3d& pt) const
|
|
{
|
|
if (IsEmpty() || !(IsClosed()))
|
|
{
|
|
return 0;
|
|
}
|
|
if (GetLength() < TOL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
AcGeTol tol;
|
|
tol.setEqualPoint(TOL);
|
|
|
|
TBPloyLine* pNew = new TBPloyLine;
|
|
*pNew = *this;
|
|
if (pNew->HasArc())
|
|
{
|
|
pNew->LinearizePLine(PI / 36.);
|
|
}
|
|
AcGePoint3d pt1 = pt;
|
|
pt1.x += 100;
|
|
|
|
AcGeRay3d rayLine(pt,pt1); //以pt为起点的水平射线
|
|
POSITION pos = pNew->m_BNodeList.GetHeadPosition();
|
|
TBNode* pNodePre = NULL;
|
|
int nTotpt = 0; //射线与多边形的交点数
|
|
while (pos != NULL)
|
|
{
|
|
TBNode* pNode = pNew->m_BNodeList.GetNext(pos);
|
|
if (pNodePre != NULL)
|
|
{
|
|
AcGeLineSeg3d line3d(pNodePre->m_pt,pNode->m_pt); //得到直线段
|
|
AcGePoint3d secPt;
|
|
if (line3d.isOn(pt,tol))
|
|
{
|
|
return 2; //点在边上
|
|
}
|
|
if (IsOverlap(pt,pt1,pNodePre->m_pt,pNode->m_pt))
|
|
{
|
|
continue;
|
|
}
|
|
else if (rayLine.isOn(pNodePre->m_pt,tol) && (pNodePre->m_pt.y<pNode->m_pt.y))
|
|
{
|
|
nTotpt++;
|
|
}
|
|
else if (rayLine.isOn(pNode->m_pt,tol) && (pNode->m_pt.y<pNodePre->m_pt.y))
|
|
{
|
|
nTotpt++;
|
|
}
|
|
else if (line3d.intersectWith(rayLine,secPt) == Adesk::kTrue &&
|
|
!rayLine.isOn(pNode->m_pt,tol) && !rayLine.isOn(pNodePre->m_pt,tol))
|
|
{
|
|
nTotpt++;
|
|
}
|
|
}
|
|
pNodePre = pNode;
|
|
}
|
|
delete pNew;
|
|
if ((nTotpt + 1) % 2 == 0)
|
|
{
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
BOOL TBPloyLine::HasArc() const
|
|
{
|
|
POSITION pos = m_BNodeList.GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
TBNode* pNode = m_BNodeList.GetNext(pos);
|
|
if (pNode->m_eType == BARCSEG && pNode->m_pArc != NULL)
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
BOOL TBPloyLine::isCircle() const
|
|
{
|
|
if (IsEmpty())
|
|
{
|
|
return 0;
|
|
}
|
|
TBPloyLine tempLine = *this;
|
|
tempLine.ClearUp();
|
|
TBNode* pHead = tempLine.Head();
|
|
if (pHead == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
if (tempLine.HasArc() && tempLine.m_BNodeList.GetCount() == 2 &&
|
|
fabs(fabs(pHead->m_pArc->m_centAngle) - 2 * PI) < TOL)
|
|
{
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
BOOL TBPloyLine::IsInXYPlane() const
|
|
{
|
|
TBNode* pHead = m_BNodeList.GetHead();
|
|
POSITION pos = m_BNodeList.GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
TBNode* pNode = m_BNodeList.GetNext(pos);
|
|
if (fabs(pHead->m_pt.z - pNode->m_pt.z) > TOL)
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
void TBPloyLine::MoveTo(AcGeVector3d& disp)
|
|
{
|
|
POSITION pos = m_BNodeList.GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
TBNode* pNode = m_BNodeList.GetNext(pos);
|
|
pNode->m_pt = pNode->m_pt + disp;
|
|
if (pNode->m_eType == BARCSEG && pNode->m_pArc != NULL)
|
|
{
|
|
pNode->m_pArc->m_centPt = pNode->m_pArc->m_centPt + disp;
|
|
}
|
|
}
|
|
}
|
|
|
|
void TBPloyLine::ReCalcSValue()
|
|
{
|
|
if (IsEmpty())
|
|
{
|
|
return;
|
|
}
|
|
|
|
POSITION pos = m_BNodeList.GetHeadPosition();
|
|
double len = 0.0;
|
|
TBNode* pNodePre = NULL;
|
|
while (pos != NULL)
|
|
{
|
|
TBNode* pNode = m_BNodeList.GetNext(pos);
|
|
if (pNodePre != NULL)
|
|
{
|
|
if (pNodePre->m_eType == BLINESEG)
|
|
{
|
|
len += pNodePre->m_pt.distanceTo(pNode->m_pt);
|
|
}
|
|
else if (pNodePre->m_eType == BARCSEG && pNodePre->m_pArc != NULL)
|
|
{
|
|
len += pNodePre->m_pArc->Length();
|
|
}
|
|
}
|
|
pNode->m_s = len;
|
|
pNodePre = pNode;
|
|
}
|
|
}
|
|
|
|
int TBPloyLine::IsZParalECSAndUcs(AcDbObjectId& objId)
|
|
{
|
|
AcDbEntity *pEnt;
|
|
acdbOpenObject(pEnt, objId, AcDb::kForRead);
|
|
|
|
CString DxfName = pEnt->isA()->dxfName();
|
|
if (DxfName == _T("LINE"))
|
|
{
|
|
AcDbLine* pLine = (AcDbLine*)(pEnt);
|
|
|
|
AcGePoint3d pt1 = pLine->startPoint();
|
|
AcGePoint3d pt2 = pLine->endPoint();
|
|
WCS2UCS(pt1);
|
|
WCS2UCS(pt2);
|
|
|
|
pEnt->close();
|
|
|
|
double d = pt1.distanceTo(pt2);
|
|
if (d <= TOL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if (fabs(pt1[Z] - pt2[Z]) / d >= TOL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
pEnt->close();
|
|
ads_point ads_ret,ads_pt = {0.,0.,1.};
|
|
ads_name pEntName;
|
|
acdbGetAdsName(pEntName,objId);
|
|
|
|
struct resbuf from,to;
|
|
from.restype = RTENAME;
|
|
ads_name_set(pEntName,from.resval.rlname); //ECS
|
|
to.restype = RTSHORT;
|
|
to.resval.rint = 1; //UCS
|
|
acedTrans(ads_pt,&from,&to,1,ads_ret); //按矢量转换
|
|
|
|
double tol = TOL;
|
|
if (fabs(ads_ret[X]) < TOL && fabs(ads_ret[Y]) < TOL && ads_ret[Z] >= 0.)
|
|
{
|
|
return 1;
|
|
}
|
|
else if (fabs(ads_ret[X]) < TOL && fabs(ads_ret[Y]) < TOL && ads_ret[Z] < 0.)
|
|
{
|
|
return 2;
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
void TBPloyLine::WCS2ECS(AcGePoint3d& pt,AcDbObjectId& objId,BOOL bVer)
|
|
{
|
|
ads_point ads_pt1,ads_ret;
|
|
ARX2AdsPt(pt,ads_pt1);
|
|
|
|
ads_name pEntName;
|
|
acdbGetAdsName(pEntName,objId);
|
|
|
|
struct resbuf from,to;
|
|
from.restype = RTSHORT;
|
|
from.resval.rint = 0;
|
|
to.restype = RTENAME;
|
|
ads_name_set(pEntName,to.resval.rlname); //ECS
|
|
acedTrans(ads_pt1,&from,&to,bVer,ads_ret);
|
|
|
|
Ads2ARXPt(ads_ret,pt);
|
|
}
|
|
|
|
void TBPloyLine::WCS2UCS(AcGePoint3d& pt,BOOL bVer)
|
|
{
|
|
ads_point ads_pt1,ads_ret;
|
|
ARX2AdsPt(pt,ads_pt1);
|
|
|
|
struct resbuf from,to;
|
|
from.restype = RTSHORT;
|
|
from.resval.rint = 0; //WCS
|
|
to.restype = RTSHORT;
|
|
to.resval.rint = 1; //UCS
|
|
|
|
acedTrans(ads_pt1,&from,&to,bVer,ads_ret);
|
|
Ads2ARXPt(ads_ret,pt);
|
|
}
|
|
|
|
void TBPloyLine::ECS2UCS(AcGePoint3d& pt,AcDbObjectId& objId,BOOL bVer)
|
|
{
|
|
ads_point ads_pt1,ads_ret;
|
|
ARX2AdsPt(pt,ads_pt1);
|
|
|
|
ads_name pEntName;
|
|
acdbGetAdsName(pEntName,objId);
|
|
|
|
struct resbuf from,to;
|
|
from.restype = RTENAME;
|
|
ads_name_set(pEntName,from.resval.rlname); //ECS
|
|
to.restype = RTSHORT;
|
|
to.resval.rint = 1;
|
|
|
|
acedTrans(ads_pt1,&from,&to,bVer,ads_ret);
|
|
Ads2ARXPt(ads_ret,pt);
|
|
}
|
|
|
|
AcGePoint3d TBPloyLine::polar(AcGePoint3d& pt0,double ang,double dist)
|
|
{
|
|
AcGePoint3d pt3d;
|
|
ads_point ads_pt,ads_ret;
|
|
ARX2AdsPt(pt0,ads_pt);
|
|
acutPolar(ads_pt,ang,dist,ads_ret);
|
|
Ads2ARXPt(ads_ret,pt3d);
|
|
return pt3d;
|
|
}
|
|
|
|
BOOL TBPloyLine::IsEqualSign(double x1,double x2)
|
|
{
|
|
if (x1 > fTOL && x2 > fTOL)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
if (x1 < fTOL && x2 < fTOL)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|