Files
envi-code/SourceCode/Code2026/tg_shs/shs_siteplan/Road.cpp
T
2026-09-28 15:28:50 +08:00

1159 lines
32 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);
}
}
}