1159 lines
33 KiB
C++
1159 lines
33 KiB
C++
#include "stdafx.h"
|
|
|
|
#include "commonRoad.h"
|
|
|
|
#include "Road.h"
|
|
|
|
AcGeTol CRoad::m_sGeTol;
|
|
|
|
// 单件线段类,用来辅助执行该线上了点排序。
|
|
class __LineSingleton
|
|
{
|
|
public:
|
|
static AcGeLineSeg2d & GetLine();
|
|
static void SetLine(const AcGeLineSeg2d &line);
|
|
static void Release();
|
|
|
|
private:
|
|
__LineSingleton (){}
|
|
~__LineSingleton(){}
|
|
|
|
private:
|
|
static AcGeLineSeg2d *m_pLine;
|
|
};
|
|
|
|
// 单件弧线类,用来辅助执行该弧线上的点排序。
|
|
class __ArcSingleton
|
|
{
|
|
public:
|
|
static AcGeCircArc2d & GetArc();
|
|
static void SetArc(const AcGeCircArc2d &arc);
|
|
static void Release();
|
|
|
|
private:
|
|
__ArcSingleton (){}
|
|
~__ArcSingleton(){}
|
|
|
|
private:
|
|
static AcGeCircArc2d *m_pArc;
|
|
};
|
|
|
|
AcGeLineSeg2d *__LineSingleton::m_pLine = NULL;
|
|
void __LineSingleton::SetLine(const AcGeLineSeg2d &line)
|
|
{
|
|
if (m_pLine == NULL)
|
|
m_pLine = new AcGeLineSeg2d(line);
|
|
|
|
else
|
|
m_pLine->set(line.startPoint(), line.endPoint());
|
|
}
|
|
|
|
AcGeLineSeg2d& __LineSingleton::GetLine()
|
|
{
|
|
ASSERT(m_pLine != NULL);
|
|
|
|
return *m_pLine;
|
|
}
|
|
|
|
void __LineSingleton::Release()
|
|
{
|
|
delete m_pLine;
|
|
m_pLine = NULL;
|
|
}
|
|
|
|
AcGeCircArc2d *__ArcSingleton::m_pArc = NULL;
|
|
void __ArcSingleton::SetArc(const AcGeCircArc2d &arc)
|
|
{
|
|
if (m_pArc == NULL)
|
|
m_pArc = new AcGeCircArc2d(arc);
|
|
else
|
|
*m_pArc = arc;
|
|
}
|
|
|
|
AcGeCircArc2d& __ArcSingleton::GetArc()
|
|
{
|
|
ASSERT(m_pArc != NULL);
|
|
|
|
return *m_pArc;
|
|
}
|
|
|
|
void __ArcSingleton::Release()
|
|
{
|
|
delete m_pArc;
|
|
m_pArc = NULL;
|
|
}
|
|
|
|
// 设置arInters最后两个参数为Attached。
|
|
void AttachEndInterStruct(AcAryInterStructPointer &arInters)
|
|
{
|
|
ASSERT(arInters.length() >= 2);
|
|
|
|
CInterStruct *pInter1 = arInters[arInters.length() - 2];
|
|
CInterStruct *pInter2 = arInters.last();
|
|
|
|
ASSERT(pInter1 != NULL);
|
|
ASSERT(pInter2 != NULL);
|
|
|
|
pInter1->SetAttachedStruct(pInter2);
|
|
pInter2->SetAttachedStruct(pInter1);
|
|
}
|
|
|
|
// 取中点,用于模板函数调用,不可删除
|
|
inline AcGePoint2d MidPoint(const AcGeCircArc2d &arc)
|
|
{
|
|
return MidPointOfArc(arc);
|
|
}
|
|
|
|
inline AcGePoint2d MidPoint(const AcGeLineSeg2d &lineseg)
|
|
{
|
|
return lineseg.midPoint();
|
|
}
|
|
|
|
// 模板函数,为实现平台无关,设置为全局函数,
|
|
template<class TSplit, class TEdgeExt, class TInter, class TRoad, class TCADEnt>
|
|
void CreateArInterStruct(const TSplit &edgeSplit, const TEdgeExt &leftEdgeExt, const TEdgeExt &rightEdgeExt,
|
|
AcAryInterStructPointer &arLeftInterStruct, AcAryInterStructPointer &arRightInterStruct,
|
|
AcAryInterStructPointer &arInterOri,
|
|
TRoad &road, TCADEnt &ent, AcGeTol &tol, TInter&)
|
|
{
|
|
// 分别判断SplintEdge的 起点、终点、中点在垂直方向上相对于道路的位置。
|
|
EPointAtRoadPerp eAtRoadMidPoint = road.PointAtRoadPerp(MidPoint(edgeSplit));
|
|
EPointAtRoadPerp eAtRoadStartPt = road.PointAtRoadPerp(edgeSplit.startPoint());
|
|
EPointAtRoadPerp eAtRoadEndPt = road.PointAtRoadPerp(edgeSplit.endPoint());
|
|
|
|
AcAryInterStructPointer *pInterStruct = NULL;
|
|
if (InRoadPerp(eAtRoadMidPoint) && InRoadPerp(eAtRoadStartPt) && InRoadPerp(eAtRoadEndPt))
|
|
{
|
|
TInter* pInter = ConInterStructInRoad(edgeSplit, ent);
|
|
// ent.AddInterStruct(pInter);
|
|
arInterOri.append(pInter);
|
|
return; // 排除边线在道路内部的情况
|
|
}
|
|
|
|
// 分别判断splitEdge的起点和终点是否在道路左边线或者右边线上(包括延长线)
|
|
// start和end代表splitline的起终,而left和right代表道路的左边,或者右边
|
|
bool bStartLeft = leftEdgeExt.isOn(edgeSplit.startPoint(), tol) == Adesk::kTrue;
|
|
bool bStartRight = rightEdgeExt.isOn(edgeSplit.startPoint(), tol) == Adesk::kTrue;
|
|
bool bEndLeft = leftEdgeExt.isOn(edgeSplit.endPoint(), tol) == Adesk::kTrue;
|
|
bool bEndRight = rightEdgeExt.isOn(edgeSplit.endPoint(), tol) == Adesk::kTrue;
|
|
|
|
if (!bStartLeft && !bStartRight && !bEndLeft && !bEndRight)
|
|
return;// 排除跟道路不相交的情况,两端都不跟道路相交
|
|
|
|
bool bStart = false, bEnd = false, bComplexOut = false, bPara = false;
|
|
EPointAtRoadInDir eComplexPos = eRoadStartOut;
|
|
if (bStartLeft || bEndLeft)
|
|
{
|
|
pInterStruct = &arLeftInterStruct;
|
|
AcGeVector2d dirAtStartOfSplit = road.LeftDirection(edgeSplit.startPoint());
|
|
AcGeVector2d dirAtEndOfSplit = road.LeftDirection(edgeSplit.endPoint());
|
|
EVecDirection eStartDir = road.SameDirection(dirAtStartOfSplit, edgeSplit, true);
|
|
EVecDirection eEndDir = road.SameDirection(dirAtEndOfSplit, edgeSplit, false);
|
|
bStart = (bStartLeft && (eStartDir == eSameDir));
|
|
bEnd = (bEndLeft && (eEndDir == eSameDir));
|
|
if ((bStartLeft && !bStart) || (bEndLeft && !bEnd))
|
|
{
|
|
ASSERT(!(bStartLeft && bEndLeft)); // 不可能起点和终点都在道路的一条边上,而且还是跨交
|
|
bStart = bStartLeft;
|
|
bEnd = bEndLeft;
|
|
if ((eStartDir == ePerpDir) || (eEndDir == ePerpDir))
|
|
{
|
|
bPara = true;
|
|
}
|
|
else
|
|
{
|
|
bComplexOut = true;
|
|
pInterStruct = &arRightInterStruct;
|
|
if (road.SameDirection(road.StartDirection(ChosePoint(edgeSplit, bStartLeft)), edgeSplit, bStartLeft) == eSameDir)
|
|
eComplexPos = eRoadStartOut;
|
|
else
|
|
eComplexPos = eRoadEndOut;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pInterStruct = &arRightInterStruct;
|
|
AcGeVector2d dirAtStartOfSplit = road.RightDirection(edgeSplit.startPoint());
|
|
AcGeVector2d dirAtEndOfSplit = road.RightDirection(edgeSplit.endPoint());
|
|
EVecDirection eStartDir = road.SameDirection(dirAtStartOfSplit, edgeSplit, true);
|
|
EVecDirection eEndDir = road.SameDirection(dirAtEndOfSplit, edgeSplit, false);
|
|
bStart = (bStartRight && (eStartDir == eSameDir));
|
|
bEnd = (bEndRight && (eEndDir == eSameDir));
|
|
if ((bStartRight && !bStart) || (bEndRight && !bEnd))
|
|
{
|
|
ASSERT(!(bStartRight && bEndRight)); // 不可能起点和终点都在道路的一条边上,而且还是跨交
|
|
bStart = bStartRight;
|
|
bEnd = bEndRight;
|
|
if ((eStartDir == ePerpDir) || (eEndDir == ePerpDir))
|
|
{
|
|
bPara = true;
|
|
}
|
|
else
|
|
{
|
|
bComplexOut = true;
|
|
pInterStruct = &arLeftInterStruct;
|
|
if (road.SameDirection(road.StartDirection(ChosePoint(edgeSplit, bStartRight)), edgeSplit, bStartRight) == eSameDir)
|
|
eComplexPos = eRoadStartOut;
|
|
else
|
|
eComplexPos = eRoadEndOut;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!bStart && !bEnd)
|
|
return;
|
|
|
|
// edgeSplit
|
|
if (bStart)
|
|
{
|
|
TInter *pInter = ConInterStruct(edgeSplit, true, road, ent, tol, bPara, FALSE, bComplexOut, eComplexPos);
|
|
pInterStruct->append(pInter);
|
|
// ent.AddInterStruct(pInter);
|
|
arInterOri.append(pInter);
|
|
}
|
|
if (bEnd)
|
|
{
|
|
TInter *pInter = ConInterStruct(edgeSplit, false, road, ent, tol, bPara, FALSE, bComplexOut, eComplexPos);
|
|
pInterStruct->append(pInter);
|
|
// ent.AddInterStruct(pInter);
|
|
arInterOri.append(pInter);
|
|
}
|
|
|
|
if (bStart && bEnd)
|
|
AttachEndInterStruct(*pInterStruct);
|
|
}
|
|
|
|
template<class TSplit, class TMidExt, class TInter, class TRoad, class TCADEnt>
|
|
void CreateArInterStructForMid(const TSplit &midSplit, const TMidExt &midExt,
|
|
AcAryInterStructPointer &arLeftInterStruct, AcAryInterStructPointer &arRightInterStruct,
|
|
TRoad &road, TCADEnt &ent, AcGeTol &tol, TInter&)
|
|
{
|
|
bool bStartOn = midExt.isOn(midSplit.startPoint(), tol) == Adesk::kTrue;
|
|
bool bEndOn = midExt.isOn(midSplit.endPoint(), tol) == Adesk::kTrue;
|
|
|
|
if (!bStartOn && !bEndOn)
|
|
return;
|
|
|
|
// 排除了不相交的情况,这里开始判断splitMid是在左边还是在右边,
|
|
AcAryInterStructPointer *pArDumpInter = NULL;
|
|
EVecDirection eVecDir = road.SameDirection(road.LeftDirection(ChosePoint(midSplit, bStartOn)), midSplit, bStartOn);
|
|
bool bPara = (eVecDir == ePerpDir);
|
|
if ((eVecDir == eSameDir) || (eVecDir == ePerpDir))
|
|
pArDumpInter = &arLeftInterStruct;
|
|
else
|
|
pArDumpInter = &arRightInterStruct;
|
|
|
|
|
|
// 直线道路跟圆弧中线的判定,可能会出现一端有两个端点的情况,这时添加的是两个Attach的结构体。
|
|
if (bStartOn)
|
|
pArDumpInter->append(ConInterStruct(midSplit, true, road, ent, tol, bPara, TRUE));
|
|
if (bEndOn)
|
|
pArDumpInter->append(ConInterStruct(midSplit, false, road, ent, tol, bPara,TRUE));
|
|
|
|
if (bStartOn && bEndOn)
|
|
AttachEndInterStruct(*pArDumpInter);
|
|
}
|
|
|
|
int __PointCompareWithLine(const void *p1, const void* p2)
|
|
{
|
|
AcGeLineSeg2d lineSeg = __LineSingleton::GetLine();
|
|
|
|
const AcGePoint2d *pPt1 = (const AcGePoint2d*)p1, *pPt2 = (const AcGePoint2d*)p2;
|
|
|
|
return PointSequence(lineSeg.direction(), *pPt1, *pPt2);
|
|
}
|
|
|
|
// 点排序
|
|
void SortPoint(const AcGeLineSeg2d &lineseg, AcArray<AcGePoint2d> &arPoint)
|
|
{
|
|
__LineSingleton::SetLine(lineseg);
|
|
|
|
AcGePoint2d *pArPoint = arPoint.asArrayPtr();
|
|
qsort(pArPoint, arPoint.length(), sizeof(AcGePoint2d), __PointCompareWithLine);
|
|
|
|
__LineSingleton::Release();
|
|
}
|
|
|
|
int __PointCompareWithArc(const void *p1, const void *p2)
|
|
{
|
|
AcGeCircArc2d arc = __ArcSingleton::GetArc();
|
|
|
|
const AcGePoint2d *pPt1 = (const AcGePoint2d*)p1, *pPt2 = (const AcGePoint2d*)p2;
|
|
return PointSequence(arc, *pPt1, *pPt2);
|
|
}
|
|
|
|
// 点排序, 排序起点是圆弧起始端所在半圆的起点,沿着圆弧的方向
|
|
void SortPoint(const AcGeCircArc2d &arc, AcArray<AcGePoint2d> &arPoint)
|
|
{
|
|
__ArcSingleton::SetArc(arc);
|
|
|
|
AcGePoint2d *pArPoint = arPoint.asArrayPtr();
|
|
qsort(pArPoint, arPoint.length(), sizeof(AcGePoint2d), __PointCompareWithArc);
|
|
|
|
__ArcSingleton::Release();
|
|
}
|
|
|
|
// 在直线的方向上比较两个点的先后顺序,顺序返回true, 逆序返回false;
|
|
bool IsPointInSequence(const AcGeLineSeg2d &lineseg, const AcGePoint2d &pt1, const AcGePoint2d &pt2)
|
|
{
|
|
return PointSequence(lineseg.direction(), pt1, pt2) == -1;
|
|
}
|
|
|
|
//在弧线的方向上比较两个点的先后顺序,顺序返回true, 逆序返回false;
|
|
bool IsPointInSequence(const AcGeCircArc2d &cirArc, const AcGePoint2d &pt1, const AcGePoint2d &pt2)
|
|
{
|
|
return PointSequence(cirArc, pt1, pt2) == -1;
|
|
}
|
|
|
|
|
|
CRoad::CRoad(double dLeftWid, double dRightWid, BOOL bDrawMid, BOOL bDrawCorner, double dCornerRadius, EFilletStyle cornerType)
|
|
: m_dLeftWid(dLeftWid), m_dRightWid(dRightWid), m_bDrawMid(bDrawMid), m_bCorner(bDrawCorner), m_dRaidus(dCornerRadius), m_eCornerType(cornerType)
|
|
{
|
|
m_sGeTol.setEqualPoint(1.0);
|
|
m_sGeTol.setEqualVector(1.0);
|
|
}
|
|
|
|
CRoad::~CRoad(void)
|
|
{
|
|
|
|
}
|
|
|
|
void CRoad::ToRegionSys(AcGePoint2d &ptLeftDown, AcGePoint2d &ptRightUp) const
|
|
{
|
|
ToRegion(ptLeftDown, ptRightUp);
|
|
ptLeftDown = AsSysUnitPoint2d(ptLeftDown);
|
|
ptRightUp = AsSysUnitPoint2d(ptRightUp);
|
|
}
|
|
|
|
EVecDirection CRoad::VecSameDirection(AcGeVector2d vec1, AcGeVector2d vec2, double dTol)
|
|
{
|
|
vec1.normalize();
|
|
vec2.normalize();
|
|
double dDot = vec1.dotProduct(vec2);
|
|
|
|
if (fabs(dDot) < dTol)
|
|
return ePerpDir;
|
|
else if (dDot < 0.0)
|
|
return eOppDir;
|
|
else return eSameDir;
|
|
}
|
|
|
|
EVecDirection CRoad::SameDirection(const AcGeVector2d &vec, const AcGeCircArc2d &arcSplit, bool bStart)
|
|
{
|
|
AcGePoint2d ptInter = bStart ? arcSplit.startPoint() : arcSplit.endPoint();
|
|
AcGeVector2d vecArcSplit = bStart ? TanVecOfArcStartPoint(arcSplit) : TanVecOfArcEndPoint(arcSplit);
|
|
|
|
return CRoad::VecSameDirection(vecArcSplit, vec, 1e-7);
|
|
}
|
|
|
|
EVecDirection CRoad::SameDirection(const AcGeVector2d &vec, const AcGeLineSeg2d &lineSplit, bool bStart)
|
|
{
|
|
AcGePoint2d ptInter = bStart ? lineSplit.startPoint() : lineSplit.endPoint();
|
|
AcGeVector2d vecArcSplit = (bStart ? lineSplit.direction() : -lineSplit.direction());
|
|
|
|
return CRoad::VecSameDirection(vecArcSplit, vec, 1e-7);
|
|
}
|
|
|
|
BOOL CRoad::IsInExtendRoad(CInterStruct *pInter) const
|
|
{
|
|
AcGePoint2d ptStart, ptEnd, ptMid;
|
|
|
|
if (pInter->ToLineInter() != NULL)
|
|
{
|
|
CLineInterStruct *pLineInter = pInter->ToLineInter();
|
|
ptStart = pLineInter->InterLine().startPoint();
|
|
ptEnd = pLineInter->InterLine().endPoint();
|
|
ptMid = MidPoint(pLineInter->InterLine());
|
|
}
|
|
else
|
|
{
|
|
CArcInterStruct *pArcInter = pInter->ToArcInter();
|
|
ptStart = pArcInter->InterArc().startPoint();
|
|
ptEnd = pArcInter->InterArc().endPoint();
|
|
ptMid = MidPoint(pArcInter->InterArc());
|
|
}
|
|
|
|
|
|
EPointAtRoadPerp eppS = PointAtRoadPerp(ptStart);
|
|
EPointAtRoadPerp eppE = PointAtRoadPerp(ptEnd);
|
|
EPointAtRoadPerp eppM = PointAtRoadPerp(ptMid);
|
|
|
|
if (!InRoadPerp(eppS) || !InRoadPerp(eppE) || !InRoadPerp(eppM))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
EPointAtRoadInDir epiS = PointAtExtendRoadInDir(ptStart);
|
|
EPointAtRoadInDir epiE = PointAtExtendRoadInDir(ptEnd);
|
|
EPointAtRoadInDir epiM = PointAtExtendRoadInDir(ptMid);
|
|
|
|
return (epiS == eInEdge && epiE == eInEdge && epiM == eInEdge);
|
|
}
|
|
|
|
|
|
// 过滤起点和终点外过多的点,起点外,或者终点外如果多个点,则只选取一个。
|
|
template <class TGeType>
|
|
void FilterSpareStartAndEndPoint(const TGeType &geSeg,
|
|
AcArray<AcGePoint2d> &arInterPoint)
|
|
{
|
|
// 过滤一下:有多个点在起点外,或者终点外的情况
|
|
int nOutNum = 0;
|
|
int nIndex = 0;
|
|
while (arInterPoint.length() >= 2) // 有两个点的时候,才会确定是否需要比较。
|
|
{
|
|
if (IsPointInSequence(geSeg, arInterPoint[nIndex], geSeg.startPoint()))
|
|
nOutNum++;
|
|
else
|
|
break;
|
|
|
|
if (nOutNum == 2)
|
|
{
|
|
arInterPoint.removeFirst();
|
|
nOutNum = 1;
|
|
}
|
|
|
|
nIndex = 1;
|
|
}
|
|
|
|
nIndex = (int)arInterPoint.length() - 1; // 定位到最后一个元素
|
|
nOutNum = 0;
|
|
while (arInterPoint.length() >= 2)
|
|
{
|
|
if (IsPointInSequence(geSeg, geSeg.endPoint(), arInterPoint[nIndex]))
|
|
{
|
|
nOutNum++;
|
|
}
|
|
else
|
|
break;
|
|
|
|
if (nOutNum == 2)
|
|
{
|
|
arInterPoint.removeLast();
|
|
nOutNum = 1;
|
|
}
|
|
|
|
nIndex = (int)(arInterPoint.length() - 1);
|
|
}
|
|
}
|
|
|
|
// 拆分单线(直线)道路 (给点)
|
|
// lineseg 所给的单线, arInterPoint 拆分点数组(顺序), arLines:拆分之后的线段
|
|
void CRoad::SplitLineEdge(const AcGeLineSeg2d &lineseg, AcArray<AcGePoint2d> &arInterPoint, AcAryLineSeg2d &arLines)
|
|
{
|
|
if (arInterPoint.isEmpty())
|
|
return;
|
|
|
|
// 过滤起点和终点外是否有超过两个点。
|
|
FilterSpareStartAndEndPoint(lineseg, arInterPoint);
|
|
|
|
// 考虑起点和终点是否需要添加为拆分点
|
|
if (IsPointInSequence(lineseg, lineseg.startPoint(), arInterPoint[0]))
|
|
arInterPoint.insertAt(0, lineseg.startPoint());
|
|
if (IsPointInSequence(lineseg, arInterPoint.last(), lineseg.endPoint()))
|
|
arInterPoint.append(lineseg.endPoint());
|
|
|
|
// 拆分
|
|
for (int index = 1; index < (int)arInterPoint.length(); index++)
|
|
{
|
|
AcGePoint2d &ptPrev = arInterPoint[index-1];
|
|
AcGePoint2d &ptIndex = arInterPoint[index];
|
|
|
|
if (ptPrev.distanceTo(ptIndex) < 1.0)
|
|
continue; // 认为是同一个点。
|
|
else
|
|
arLines.append(AcGeLineSeg2d(ptPrev, ptIndex));
|
|
}
|
|
}
|
|
|
|
// 拆分圆弧道路:
|
|
// arc:将要拆分的圆弧; arInterPioint,拆分点数组(顺序); arArcs:拆分之后的圆弧道路数组。
|
|
void CRoad::SplitArcEdge(const AcGeCircArc2d &arc, AcArray<AcGePoint2d> &arInterPoint, AcAryCircArc2d &arArcs)
|
|
{
|
|
if (arInterPoint.isEmpty())
|
|
return;
|
|
|
|
FilterSpareStartAndEndPoint(arc, arInterPoint);
|
|
|
|
if (IsPointInSequence(arc, arc.startPoint(), arInterPoint[0]))
|
|
arInterPoint.insertAt(0, arc.startPoint());
|
|
if (IsPointInSequence(arc, arInterPoint.last(), arc.endPoint()))
|
|
arInterPoint.append(arc.endPoint());
|
|
for (int index = 1; index < (int)arInterPoint.length(); index++)
|
|
{
|
|
AcGePoint2d &ptPrev = arInterPoint[index-1];
|
|
AcGePoint2d &ptIndex = arInterPoint[index];
|
|
|
|
if (ptPrev.distanceTo(ptIndex) < 1.0)
|
|
continue; // 认为是同一个点。
|
|
else
|
|
{
|
|
arArcs.append(ConNewArc(arc, ptPrev, ptIndex));
|
|
}
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// CLineRoad
|
|
|
|
AcGeLineSeg2d CLineRoad::LeftLine() const
|
|
{
|
|
return TRoadCommon::LeftLine(m_midLine, HalfWid());
|
|
}
|
|
AcGeLineSeg2d CLineRoad::RightLine() const
|
|
{
|
|
return TRoadCommon::RightLine(m_midLine, HalfWid());
|
|
}
|
|
AcGeLineSeg2d CLineRoad::MidLine() const
|
|
{
|
|
return m_midLine;
|
|
}
|
|
|
|
TGGeCurveSegment CLineRoad::ToCurveSeg(int nFlag) const // 0,中线;1,左边线;2,右边线
|
|
{
|
|
TGGeCurveSegment curve;
|
|
if (nFlag == 0)
|
|
curve.SetLine(MidLine().startPoint(), MidLine().endPoint());
|
|
else if (nFlag == 1)
|
|
curve.SetLine(LeftLine().startPoint(), LeftLine().endPoint());
|
|
else
|
|
curve.SetLine(RightLine().startPoint(), RightLine().endPoint());
|
|
|
|
return curve;
|
|
}
|
|
|
|
EPointAtRoadPerp CLineRoad::PointAtRoadPerp(const AcGePoint2d &pt, double dTol) const
|
|
{
|
|
EPointToLine el = PointToLineSegPerp(LeftLine(), pt, dTol);
|
|
EPointToLine er = PointToLineSegPerp(RightLine(), pt, dTol);
|
|
|
|
if (el == eLeft)
|
|
return eRoadLeftSide;
|
|
else if (el == eOnLine)
|
|
return eRoadLeftEdge;
|
|
else
|
|
{
|
|
if (er == eLeft)
|
|
return eInRoad;
|
|
else if (er == eOnLine)
|
|
return eRoadRightEdge;
|
|
else
|
|
return eRoadRightSide;
|
|
}
|
|
|
|
|
|
}
|
|
EPointAtRoadInDir CLineRoad::PointAtRoadInDir(const AcGePoint2d &pt, double dTol ) const
|
|
{
|
|
switch (PointToLineSegDir(MidLine(), pt, dTol))
|
|
{
|
|
case eStartOut:
|
|
case eStartPoint:
|
|
return eRoadStartOut;
|
|
break;
|
|
case eEndOut:
|
|
case eEndPoint:
|
|
return eRoadEndOut;
|
|
break;
|
|
default:
|
|
return eInEdge;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
EPointAtRoadInDir CLineRoad::PointAtExtendRoadInDir(const AcGePoint2d &pt, double dTol /* = 1.0 */) const
|
|
{
|
|
// 去圆弧上的各点
|
|
switch (PointToLineSegDir(ExtendLine(MidLine(), TolForSplit(), TolForSplit()), pt, dTol))
|
|
{
|
|
case eStartOut:
|
|
return eRoadStartOut;
|
|
break;
|
|
case eEndOut:
|
|
return eRoadEndOut;
|
|
break;
|
|
default:
|
|
return eInEdge;
|
|
}
|
|
}
|
|
|
|
void CLineRoad::ToRegion(AcGePoint2d &ptLeftDown, AcGePoint2d &ptRightUp) const
|
|
{
|
|
double dTol = TolForRegion();
|
|
|
|
AcGePoint2d ptls = LeftLine().startPoint();
|
|
AcGePoint2d ptle = LeftLine().endPoint();
|
|
AcGePoint2d ptrs = RightLine().startPoint();
|
|
AcGePoint2d ptre = RightLine().endPoint();
|
|
// 找四个点的最小值。
|
|
double xMin = MIN(MIN(ptls.x, ptle.x), MIN(ptrs.x, ptre.x));
|
|
double xMax = MAX(MAX(ptls.x, ptle.x), MAX(ptrs.x, ptre.x));
|
|
double yMin = MIN(MIN(ptls.y, ptle.y), MIN(ptrs.y, ptre.x));
|
|
double yMax = MAX(MAX(ptls.y, ptle.y), MAX(ptrs.y, ptre.y));
|
|
|
|
xMin -= dTol;
|
|
xMax += dTol;
|
|
yMin -= dTol;
|
|
yMax += dTol;
|
|
|
|
ptLeftDown.x = xMin;
|
|
ptLeftDown.y = yMin;
|
|
ptRightUp.x = xMax;
|
|
ptRightUp.y = yMax;
|
|
}
|
|
|
|
CLineRoad::CLineRoad(double dLeftWid, double dRightWid,
|
|
BOOL bDrawMid, BOOL bDrawCorner, double dCornerRadius,
|
|
EFilletStyle cornerType, const AcGeLineSeg2d &midLine)
|
|
: CRoad(dLeftWid, dRightWid, bDrawMid, bDrawCorner, dCornerRadius, cornerType), m_midLine(midLine)
|
|
{
|
|
|
|
}
|
|
|
|
CLineRoad::~CLineRoad(){}
|
|
|
|
// 直线道路的左右方向跟参数无关
|
|
AcGeVector2d CLineRoad::LeftDirection(const AcGePoint2d &point) const
|
|
{
|
|
return MidLine().direction().perpVector();
|
|
}
|
|
AcGeVector2d CLineRoad::RightDirection(const AcGePoint2d &point) const
|
|
{
|
|
return -LeftDirection(point);
|
|
}
|
|
AcGeVector2d CLineRoad::StartDirection(const AcGePoint2d &point)const
|
|
{
|
|
return -EndDirection(point);
|
|
}
|
|
AcGeVector2d CLineRoad::EndDirection(const AcGePoint2d &point)const
|
|
{
|
|
return MidLine().direction();
|
|
}
|
|
// 把直线道路识别为interStruct数组;
|
|
// LineEdge: 直线路边,leftInters: 道路左侧interStruct数组, rightInters: 道路右侧interStruct数组
|
|
void CLineRoad::SplitEdge(const AcGeLineSeg2d &lineEdge,
|
|
AcAryInterStructPointer &leftInters, AcAryInterStructPointer &rightInters,
|
|
CLineCADEntEdgeAdapter &ent, AcAryInterStructPointer &arInterOri) const
|
|
{
|
|
double dTol = TolForSplit();
|
|
AcArray<AcGePoint2d> arInterPoint; // 交点数组
|
|
AcAryLineSeg2d arLines; // 拆分出来的线
|
|
AcGeLineSeg2d leftEdge = LeftLine(), rightEdge = RightLine();
|
|
AcGeLineSeg2d leftEdgeExt = ExtendLine(leftEdge, dTol, dTol), rightEdgeExt = ExtendLine(rightEdge, dTol, dTol);
|
|
|
|
|
|
// 找交点
|
|
{
|
|
AcGePoint2d ptInter;
|
|
AcGeLineSeg2d lineEdgeExt = ExtendLine(lineEdge, dTol, dTol);
|
|
if (lineEdgeExt.intersectWith(leftEdgeExt, ptInter) == Adesk::kTrue)
|
|
{
|
|
arInterPoint.append(ptInter);
|
|
}
|
|
if (lineEdgeExt.intersectWith(rightEdgeExt, ptInter) == Adesk::kTrue)
|
|
{
|
|
arInterPoint.append(ptInter);
|
|
}
|
|
}
|
|
|
|
// 点排序,
|
|
SortPoint(lineEdge, arInterPoint);
|
|
|
|
// 拆分
|
|
SplitLineEdge(lineEdge, arInterPoint, arLines);
|
|
|
|
// 遍历新拆出来的所有路段,并且构造interStruct结构体。
|
|
for (int index = 0; index < (int)arLines.length(); index++)
|
|
{
|
|
AcGeLineSeg2d &lineSplit = arLines[index];
|
|
|
|
MyLineSeg _lineSplit(lineSplit);
|
|
MyLineSeg _leftEdge(leftEdge), _leftEdgeExt(leftEdgeExt), _rightEdge(rightEdge), _rightEdgeExt(rightEdgeExt);
|
|
|
|
CLineInterStruct xx = CLineInterStruct::DumpStruct();
|
|
CreateArInterStruct(lineSplit, leftEdgeExt, rightEdgeExt, leftInters, rightInters, arInterOri,
|
|
*this, ent, m_sGeTol, xx);
|
|
}
|
|
}
|
|
|
|
|
|
// 把圆弧道路识别为interStruct数组;
|
|
// ArcEdge: 直线路边,leftInters: 道路左侧interStruct数组, rightInters: 道路右侧interStruct数组
|
|
void CLineRoad::SplitEdge(const AcGeCircArc2d &arcEdge,
|
|
AcAryInterStructPointer &leftInters, AcAryInterStructPointer &rightInters,
|
|
CArcCADEntEdgeAdapter &ent, AcAryInterStructPointer &arInterOri) const
|
|
{
|
|
double dTol = TolForSplit();
|
|
AcArray<AcGePoint2d> arInterPoint; // 交点数组
|
|
AcAryCircArc2d arArcs; // 拆分出来的线
|
|
AcGeLineSeg2d leftEdge = LeftLine(), rightEdge = RightLine();
|
|
AcGeCircArc2d arcEdgeExt = ExtendArc(arcEdge, dTol, dTol);
|
|
AcGeLineSeg2d leftEdgeExt = ExtendLine(leftEdge, dTol, dTol), rightEdgeExt = ExtendLine(rightEdge, dTol, dTol);
|
|
|
|
// 找交点
|
|
{
|
|
AcGePoint2d ptInter1, ptInter2;
|
|
int nNum = -1;
|
|
if (arcEdgeExt.intersectWith(leftEdgeExt, nNum, ptInter1, ptInter2) == Adesk::kTrue)
|
|
{
|
|
arInterPoint.append(ptInter1);
|
|
if (nNum == 2)
|
|
arInterPoint.append(ptInter2);
|
|
}
|
|
if (arcEdgeExt.intersectWith(rightEdgeExt, nNum, ptInter1, ptInter2) == Adesk::kTrue)
|
|
{
|
|
arInterPoint.append(ptInter1);
|
|
if (nNum == 2)
|
|
arInterPoint.append(ptInter2);
|
|
}
|
|
}
|
|
|
|
// 点排序,
|
|
SortPoint(arcEdge, arInterPoint);
|
|
|
|
// 拆分
|
|
SplitArcEdge(arcEdge, arInterPoint, arArcs);
|
|
|
|
// 遍历新拆出来的所有路段,并且构造interStruct结构体。
|
|
for (int index = 0; index < (int)arArcs.length(); index++)
|
|
{
|
|
AcGeCircArc2d &arcSplit = arArcs[index];
|
|
CArcInterStruct xx = CArcInterStruct::DumpStruct();
|
|
CreateArInterStruct(arcSplit, leftEdgeExt, rightEdgeExt, leftInters, rightInters, arInterOri,
|
|
*this, ent, m_sGeTol, xx);
|
|
}
|
|
}
|
|
|
|
void CLineRoad::SplitMid(const AcGeLineSeg2d &lineseg,
|
|
AcAryInterStructPointer &arLeftDump,
|
|
AcAryInterStructPointer &arRightDump,
|
|
CLineCADEntEdgeAdapter &ent) const
|
|
{
|
|
ClearAcaryAll(arLeftDump);
|
|
ClearAcaryAll(arRightDump);
|
|
|
|
if (!IsDrawMid())
|
|
return;
|
|
|
|
AcGeLineSeg2d linemid = MidLine();
|
|
double dTol = TolForSplit();
|
|
|
|
AcGeLineSeg2d lineMidExt = ExtendLine(linemid, dTol, dTol);
|
|
AcGeLineSeg2d linesegExt = ExtendLine(lineseg, dTol, dTol);
|
|
|
|
AcGePoint2d ptInter;
|
|
if (lineMidExt.intersectWith(linesegExt, ptInter))
|
|
{
|
|
AcArray<AcGePoint2d> arPtInter;
|
|
arPtInter.append(ptInter);
|
|
|
|
AcAryLineSeg2d arLines;
|
|
SplitLineEdge(lineseg, arPtInter, arLines);
|
|
|
|
for (int i = 0; i < (int)arLines.length(); i++)
|
|
{
|
|
AcGeLineSeg2d &lineSplit = arLines[i];
|
|
// 构造interStruct结构体,并且添加:
|
|
bool bStartOn = lineMidExt.isOn(lineSplit.startPoint(), m_sGeTol) == Adesk::kTrue;
|
|
bool bEndOn = lineMidExt.isOn(lineSplit.endPoint(), m_sGeTol) == Adesk::kTrue;
|
|
|
|
if (!bStartOn && !bEndOn)
|
|
continue;
|
|
if (bStartOn && bEndOn)
|
|
continue;
|
|
|
|
// 排除了不相交的情况,这里开始判断splitMid是在左边还是在右边,
|
|
AcAryInterStructPointer *pArDumpInter = NULL;
|
|
AcGeVector2d vecRoadLeft = LeftDirection(bStartOn ? lineSplit.startPoint() : lineSplit.endPoint());
|
|
EVecDirection eVecDir = SameDirection(vecRoadLeft, lineSplit, bStartOn);
|
|
bool bPara = (eVecDir == ePerpDir);
|
|
if ((eVecDir == eSameDir) || (eVecDir == ePerpDir))
|
|
pArDumpInter = &arLeftDump;
|
|
else
|
|
pArDumpInter = &arRightDump;
|
|
|
|
//注意:直线道路跟直线道路不可能存在连个交点,因此只能添加一个interStruct结构体
|
|
// 如果是其他情况:直线-圆弧,圆弧-圆弧,这时可能会产生了两个交点,此次,要添加两个interStruct,并且,设置这两个itnerStruct--BeAttached.
|
|
pArDumpInter->append(ConInterStruct(lineSplit, bStartOn, *this, ent, m_sGeTol, bPara, TRUE));
|
|
}
|
|
}
|
|
}
|
|
|
|
// 直线道路的中线对圆弧中心进行拆分,并且生成interStruct数组。
|
|
void CLineRoad::SplitMid(const AcGeCircArc2d &arc,
|
|
AcAryInterStructPointer &arLeftDump,
|
|
AcAryInterStructPointer &arRightDump,
|
|
CArcCADEntEdgeAdapter &ent)const
|
|
{
|
|
ClearAcaryAll(arLeftDump);
|
|
ClearAcaryAll(arRightDump);
|
|
|
|
if (!IsDrawMid())
|
|
return;
|
|
|
|
double dTol = TolForSplit();
|
|
AcGeLineSeg2d linemid = MidLine();
|
|
AcGeLineSeg2d lineMidExt = ExtendLine(linemid, dTol, dTol);
|
|
|
|
AcGeCircArc2d arcExt = ExtendArc(arc, dTol, dTol);
|
|
|
|
AcGePoint2d ptInter1, ptInter2;
|
|
int nNum = -1;
|
|
if (arcExt.intersectWith(lineMidExt, nNum, ptInter1, ptInter2))
|
|
{
|
|
AcArray<AcGePoint2d> arPtInter;
|
|
arPtInter.append(ptInter1);
|
|
if (nNum == 2)
|
|
arPtInter.append(ptInter2);
|
|
|
|
if (arPtInter.length() == 2)
|
|
SortPoint(arc, arPtInter);
|
|
AcAryCircArc2d arArc;
|
|
SplitArcEdge(arc, arPtInter, arArc);
|
|
|
|
for (int i = 0; i < (int)arArc.length(); i++)
|
|
{
|
|
AcGeCircArc2d &arcSplit = arArc[i];
|
|
// 构造interStruct结构体,并且添加:
|
|
CArcInterStruct xx = CArcInterStruct::DumpStruct();
|
|
CreateArInterStructForMid(arcSplit, lineMidExt, arLeftDump, arRightDump,
|
|
*this, ent, m_sGeTol, xx);
|
|
}
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// CArcRoad
|
|
CArcRoad::CArcRoad(double dLeftWid, double dRightWid,
|
|
BOOL bDrawMid, BOOL bDrawCorner, double dCornerRadius,
|
|
EFilletStyle cornerType, const AcGeCircArc2d &midArc)
|
|
: CRoad(dLeftWid, dRightWid, bDrawMid, bDrawCorner, dCornerRadius, cornerType), m_midArc(midArc)
|
|
{
|
|
|
|
}
|
|
|
|
CArcRoad::~CArcRoad(){}
|
|
|
|
AcGeVector2d CArcRoad::LeftDirection(const AcGePoint2d &point) const
|
|
{
|
|
if (MidArc().isClockWise())
|
|
{
|
|
return point - MidArc().center();
|
|
}
|
|
else
|
|
return MidArc().center() - point;
|
|
}
|
|
|
|
AcGeVector2d CArcRoad::RightDirection(const AcGePoint2d &point) const
|
|
{
|
|
return -LeftDirection(point);
|
|
}
|
|
|
|
AcGeVector2d CArcRoad::StartDirection(const AcGePoint2d &point) const
|
|
{
|
|
return LeftDirection(point).perpVector();
|
|
}
|
|
AcGeVector2d CArcRoad::EndDirection(const AcGePoint2d &point) const
|
|
{
|
|
return -StartDirection(point);
|
|
}
|
|
|
|
AcGeCircArc2d CArcRoad::LeftArc() const
|
|
{
|
|
return TRoadCommon::LeftArc(m_midArc, HalfWid());
|
|
}
|
|
AcGeCircArc2d CArcRoad::RightArc() const
|
|
{
|
|
return TRoadCommon::RightArc(m_midArc, HalfWid());
|
|
}
|
|
AcGeCircArc2d CArcRoad::MidArc() const
|
|
{
|
|
return m_midArc;
|
|
}
|
|
|
|
TGGeCurveSegment CArcRoad::ToCurveSeg(int nFlag) const // 0,中线;1,左边线;2,右边线
|
|
{
|
|
// AcGeCircArc2d acgeArc;
|
|
// if (nFlag == 0)
|
|
// acgeArc = MidArc();
|
|
// else if (nFlag == 1)
|
|
// acgeArc = LeftArc();
|
|
// else
|
|
// acgeArc = RightArc();
|
|
//
|
|
//
|
|
// TGGeArc geArc(asDblArray(acgeArc.center()),
|
|
// acgeArc.radius(),
|
|
// (acgeArc.isClockWise() ? acgeArc.endAng() : acgeArc.startAng()),
|
|
// (acgeArc.isClockWise() ? acgeArc.startAng() : acgeArc.endAng()));
|
|
//
|
|
// TGGeCurveSegment geCurve;
|
|
// geCurve = geArc;
|
|
// return geCurve;
|
|
|
|
AcGeCircArc2d arc;
|
|
if (nFlag == 0)
|
|
arc = MidArc();
|
|
else if (nFlag == 1)
|
|
arc = LeftArc();
|
|
else
|
|
arc = RightArc();
|
|
|
|
return TGGeCurveSegment(arc.isClockWise() ? arc.endPoint() : arc.startPoint(),
|
|
arc.isClockWise() ? arc.startPoint() : arc.endPoint(),
|
|
NormalAngle(arc.endAng() - arc.startAng())
|
|
);
|
|
}
|
|
|
|
EPointAtRoadPerp CArcRoad::PointAtRoadPerp(const AcGePoint2d &pt, double dTol) const
|
|
{
|
|
EPointToLine el = PointToArcPerp(LeftArc(), pt, dTol);
|
|
EPointToLine er = PointToArcPerp(RightArc(), pt, dTol);
|
|
|
|
if (el == eLeft)
|
|
return eRoadLeftSide;
|
|
else if (el == eOnLine)
|
|
return eRoadLeftEdge;
|
|
else
|
|
{
|
|
if (er == eLeft)
|
|
return eInRoad;
|
|
else if (er == eOnLine)
|
|
return eRoadRightEdge;
|
|
else
|
|
return eRoadRightSide;
|
|
}
|
|
}
|
|
|
|
// 点相对于圆弧的位置:
|
|
// 算法:取midArc,取起始角度,终止角度,反向中间角度。计算pt相对于反向中间角度的夹角
|
|
EPointAtRoadInDir CArcRoad::PointAtRoadInDir(const AcGePoint2d &pt, double dTol ) const
|
|
{
|
|
// 去圆弧上的各点
|
|
switch (PointToArcDir(MidArc(), pt, dTol))
|
|
{
|
|
case eStartOut:
|
|
case eStartPoint:
|
|
return eRoadStartOut;
|
|
break;
|
|
case eEndOut:
|
|
case eEndPoint:
|
|
return eRoadEndOut;
|
|
break;
|
|
default:
|
|
return eInEdge;
|
|
}
|
|
}
|
|
|
|
EPointAtRoadInDir CArcRoad::PointAtExtendRoadInDir(const AcGePoint2d &pt, double dTol /* = 1.0 */) const
|
|
{
|
|
// 去圆弧上的各点
|
|
switch (PointToArcDir(ExtendArc(MidArc(), TolForSplit(), TolForSplit()), pt, dTol))
|
|
{
|
|
case eStartOut:
|
|
return eRoadStartOut;
|
|
break;
|
|
case eEndOut:
|
|
return eRoadEndOut;
|
|
break;
|
|
default:
|
|
return eInEdge;
|
|
}
|
|
}
|
|
|
|
void CArcRoad::ToRegion(AcGePoint2d &ptLeftDown, AcGePoint2d &ptRightUp) const
|
|
{
|
|
double dTol = TolForRegion();
|
|
|
|
AcGePoint2d ptCenter = MidArc().center();
|
|
double dRadius = MidArc().radius();
|
|
|
|
ptLeftDown.x = ptCenter.x - dRadius - dTol;
|
|
ptLeftDown.y = ptCenter.y - dRadius - dTol;
|
|
ptRightUp.x = ptCenter.x + dRadius + dTol;
|
|
ptRightUp.y = ptCenter.y + dRadius + dTol;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// CArcRoad
|
|
// 把直线道路识别为interStruct数组;
|
|
// LineEdge: 直线路边,leftInters: 道路左侧interStruct数组, rightInters: 道路右侧interStruct数组
|
|
void CArcRoad::SplitEdge(const AcGeLineSeg2d &lineEdge,
|
|
AcAryInterStructPointer &leftInters, AcAryInterStructPointer &rightInters,
|
|
CLineCADEntEdgeAdapter &ent, AcAryInterStructPointer &arInterOri) const
|
|
{
|
|
// 定义数据:
|
|
double dTol = TolForSplit();
|
|
AcArray<AcGePoint2d> arInterPoint;
|
|
AcAryLineSeg2d arLines;
|
|
AcGeCircArc2d leftEdge = LeftArc(), rightEdge = RightArc();
|
|
AcGeCircArc2d leftEdgeExt = ExtendArc(leftEdge, dTol, dTol), rightEdgeExt = ExtendArc(rightEdge, dTol, dTol);
|
|
|
|
// 找交点
|
|
{
|
|
AcGeLineSeg2d lineEdgeExt = ExtendLine(lineEdge, dTol, dTol);
|
|
AcGePoint2d ptInterDump1, ptInterDump2;
|
|
int nNum = 0;
|
|
if (leftEdgeExt.intersectWith(lineEdgeExt, nNum, ptInterDump1, ptInterDump2))
|
|
{
|
|
arInterPoint.append(ptInterDump1);
|
|
if (nNum == 2)
|
|
arInterPoint.append(ptInterDump2);
|
|
|
|
}
|
|
if (rightEdgeExt.intersectWith(lineEdgeExt, nNum, ptInterDump1, ptInterDump2))
|
|
{
|
|
arInterPoint.append(ptInterDump1);
|
|
if (nNum == 2)
|
|
arInterPoint.append(ptInterDump2);
|
|
|
|
}
|
|
}
|
|
// 点排序
|
|
SortPoint(lineEdge, arInterPoint);
|
|
|
|
// 拆分
|
|
SplitLineEdge(lineEdge, arInterPoint, arLines);
|
|
|
|
// 遍历,获取数据
|
|
for (int index = 0; index < (int)arLines.length(); index++)
|
|
{
|
|
AcGeLineSeg2d &lineSplit = arLines[index];
|
|
|
|
CLineInterStruct xx = CLineInterStruct::DumpStruct();
|
|
CreateArInterStruct(lineSplit, leftEdgeExt, rightEdgeExt, leftInters, rightInters, arInterOri,
|
|
*this, ent, m_sGeTol, xx);
|
|
}
|
|
|
|
}
|
|
|
|
// 把圆弧道路识别为interStruct数组;
|
|
// ArcEdge: 直线路边,leftInters: 道路左侧interStruct数组, rightInters: 道路右侧interStruct数组
|
|
void CArcRoad::SplitEdge(const AcGeCircArc2d &arcEdge,
|
|
AcAryInterStructPointer &leftInters, AcAryInterStructPointer &rightInters,
|
|
CArcCADEntEdgeAdapter &ent, AcAryInterStructPointer &arInterOri) const
|
|
{
|
|
AcArray<AcGePoint2d> arInterPoint;
|
|
AcAryCircArc2d arArcs;
|
|
double dTol = TolForSplit();
|
|
AcGeCircArc2d leftEdge = LeftArc(), rightEdge = RightArc();
|
|
AcGeCircArc2d leftEdgeExt = ExtendArc(leftEdge, dTol, dTol), rightEdgeExt = ExtendArc(rightEdge, dTol, dTol);
|
|
AcGeCircArc2d arcEdgeExt = ExtendArc(arcEdge, dTol, dTol);
|
|
|
|
// 找交点
|
|
{
|
|
AcGePoint2d ptInterDump1, ptInterDump2;
|
|
int nNum = -1;
|
|
if (arcEdgeExt.intersectWith(leftEdgeExt, nNum, ptInterDump1, ptInterDump2))
|
|
{
|
|
arInterPoint.append(ptInterDump1);
|
|
if (nNum == 2)
|
|
arInterPoint.append(ptInterDump2);
|
|
}
|
|
if (arcEdgeExt.intersectWith(rightEdgeExt, nNum, ptInterDump1, ptInterDump2))
|
|
{
|
|
arInterPoint.append(ptInterDump1);
|
|
if (nNum == 2)
|
|
arInterPoint.append(ptInterDump2);
|
|
}
|
|
}
|
|
// 排序
|
|
SortPoint(arcEdge, arInterPoint);
|
|
// 拆分
|
|
SplitArcEdge(arcEdge, arInterPoint, arArcs);
|
|
// 遍历拆分结果,并且生成interStruct数据
|
|
for (int index = 0; index < (int)arArcs.length(); index++)
|
|
{
|
|
AcGeCircArc2d &arcSplit = arArcs[index];
|
|
CArcInterStruct xx = CArcInterStruct::DumpStruct();
|
|
CreateArInterStruct(arcSplit, leftEdgeExt, rightEdgeExt, leftInters, rightInters, arInterOri,
|
|
*this, ent, m_sGeTol, xx);
|
|
}
|
|
}
|
|
|
|
void CArcRoad::SplitMid(const AcGeLineSeg2d &lineseg,
|
|
AcAryInterStructPointer &arLeftDump,
|
|
AcAryInterStructPointer &arRightDump,
|
|
CLineCADEntEdgeAdapter &ent) const
|
|
{
|
|
ClearAcaryAll(arLeftDump);
|
|
ClearAcaryAll(arRightDump);
|
|
|
|
if (!IsDrawMid())
|
|
return;
|
|
|
|
double dTol = TolForSplit();
|
|
AcGeCircArc2d arcMid = MidArc();
|
|
AcGeCircArc2d arcMidExt = ExtendArc(arcMid, dTol, dTol);
|
|
|
|
AcGeLineSeg2d lineExt = ExtendLine(lineseg, dTol, dTol);
|
|
|
|
AcGePoint2d ptInter1, ptInter2;
|
|
int nNum = -1;
|
|
if (arcMidExt.intersectWith(lineExt, nNum, ptInter1, ptInter2))
|
|
{
|
|
AcArray<AcGePoint2d> arPtInter;
|
|
arPtInter.append(ptInter1);
|
|
if (nNum == 2)
|
|
arPtInter.append(ptInter2);
|
|
|
|
if (arPtInter.length() == 2)
|
|
SortPoint(lineseg, arPtInter);
|
|
|
|
AcAryLineSeg2d arLine;
|
|
SplitLineEdge(lineseg, arPtInter, arLine);
|
|
|
|
for (int i = 0; i < (int)arLine.length(); i++)
|
|
{
|
|
AcGeLineSeg2d &lineSplit = arLine[i];
|
|
// 构造interStruct结构体,并且添加:
|
|
CLineInterStruct xx = CLineInterStruct::DumpStruct();
|
|
CreateArInterStructForMid(lineSplit, arcMidExt, arLeftDump, arRightDump,
|
|
*this, ent, m_sGeTol, xx);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CArcRoad::SplitMid(const AcGeCircArc2d &arc,
|
|
AcAryInterStructPointer &arLeftDump,
|
|
AcAryInterStructPointer &arRightDump,
|
|
CArcCADEntEdgeAdapter &ent) const
|
|
{
|
|
ClearAcaryAll(arLeftDump);
|
|
ClearAcaryAll(arRightDump);
|
|
|
|
if (!IsDrawMid())
|
|
return;
|
|
|
|
double dTol = TolForSplit();
|
|
AcGeCircArc2d arcMid = MidArc();
|
|
AcGeCircArc2d arcMidExt = ExtendArc(arcMid, dTol, dTol);
|
|
|
|
AcGeCircArc2d arcExt = ExtendArc(arc, dTol, dTol);
|
|
|
|
AcGePoint2d ptInter1, ptInter2;
|
|
int nNum = -1;
|
|
if (arcMidExt.intersectWith(arcExt, nNum, ptInter1, ptInter2))
|
|
{
|
|
AcArray<AcGePoint2d> arPtInter;
|
|
arPtInter.append(ptInter1);
|
|
if (nNum == 2)
|
|
arPtInter.append(ptInter2);
|
|
|
|
if (arPtInter.length() == 2)
|
|
SortPoint(arc, arPtInter);
|
|
|
|
AcAryCircArc2d arArc;
|
|
SplitArcEdge(arc, arPtInter, arArc);
|
|
|
|
for (int i = 0; i < (int)arArc.length(); i++)
|
|
{
|
|
AcGeCircArc2d &arcSplit = arArc[i];
|
|
// 构造interStruct结构体,并且添加:
|
|
CLineInterStruct xx = CLineInterStruct::DumpStruct();
|
|
CreateArInterStructForMid(arcSplit, arcMidExt, arLeftDump, arRightDump,
|
|
*this, ent, m_sGeTol, xx);
|
|
}
|
|
}
|
|
} |