674 lines
20 KiB
C++
674 lines
20 KiB
C++
#include "stdafx.h"
|
|
#include "commonRoad.h"
|
|
#include "CADEntFilRoadAdapter.h"
|
|
#include "RoadArith.h"
|
|
#include "FilroadConnect.h"
|
|
|
|
double CFilroadConnect::m_dAngleTol = 0.017; // 相等弧度误差,1°。
|
|
AcGeTol CFilroadConnect::m_geTolInter;
|
|
|
|
|
|
struct SEndTestConnect
|
|
{
|
|
SEndTestConnect(BOOL bss, BOOL bse, BOOL bes, BOOL bee)
|
|
{
|
|
m_bFourcase[0] = bss;
|
|
m_bFourcase[1] = bse;
|
|
m_bFourcase[2] = bes;
|
|
m_bFourcase[3] = bee;
|
|
}
|
|
|
|
void Start(){nIndex = 0;}
|
|
BOOL End(){return nIndex > 3;}
|
|
void Next() {nIndex++;}
|
|
BOOL Get(BOOL &bStart1, BOOL &bStart2);
|
|
|
|
int nIndex;
|
|
BOOL m_bFourcase[4];
|
|
};
|
|
|
|
BOOL SEndTestConnect::Get(BOOL &bStart1, BOOL &bStart2)
|
|
{
|
|
if (!m_bFourcase[nIndex])
|
|
return FALSE;
|
|
else
|
|
{
|
|
switch (nIndex)
|
|
{
|
|
case 0:
|
|
bStart1 = bStart2 = TRUE;
|
|
break;
|
|
case 1:
|
|
bStart1 = TRUE;
|
|
bStart2 = FALSE;
|
|
break;
|
|
case 2:
|
|
bStart1 = FALSE;
|
|
bStart2 = TRUE;
|
|
break;
|
|
case 3:
|
|
bStart1 = bStart2 = FALSE;
|
|
break;
|
|
default:
|
|
ASSERT(0);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
template <class TCADEntFilroadAdatper1, class TCADEntFilroadAdatper2>
|
|
BOOL TestEndPointInter(TCADEntFilroadAdatper1 *pEnt1, TCADEntFilroadAdatper2 *pEnt2,
|
|
BOOL &bInterss, BOOL &bInterse, BOOL &bInteres, BOOL &bInteree, const AcGeTol &tol)
|
|
{
|
|
ASSERT(pEnt1 != NULL);
|
|
ASSERT(pEnt2 != NULL);
|
|
|
|
bInterss = bInterse = bInteres = bInteree = FALSE;
|
|
|
|
if (pEnt1->IsStartLinked() || pEnt2->IsStartLinked())
|
|
bInterss = FALSE;
|
|
else
|
|
bInterss = pEnt1->OriginSeg().startPoint().isEqualTo(pEnt2->OriginSeg().startPoint(), tol);
|
|
|
|
if (pEnt1->IsStartLinked() || pEnt2->IsEndLinked())
|
|
bInterse = FALSE;
|
|
else
|
|
bInterse = pEnt1->OriginSeg().startPoint().isEqualTo(pEnt2->OriginSeg().endPoint(), tol);
|
|
|
|
if (pEnt1->IsEndLinked() || pEnt2->IsStartLinked())
|
|
bInteres = FALSE;
|
|
else
|
|
bInteres = pEnt1->OriginSeg().endPoint().isEqualTo(pEnt2->OriginSeg().startPoint(), tol);
|
|
|
|
if (pEnt1->IsEndLinked() || pEnt2->IsEndLinked())
|
|
bInteree = FALSE;
|
|
else
|
|
bInteree = pEnt1->OriginSeg().endPoint().isEqualTo(pEnt2->OriginSeg().endPoint(), tol);
|
|
|
|
|
|
// 如果有一个点跟两个点都发生关系,则不生成返回false;
|
|
if((bInterss && bInterse) ||
|
|
(bInteres && bInteree) ||
|
|
(bInterss && bInteres) ||
|
|
(bInterse && bInteree))
|
|
return FALSE;
|
|
|
|
if (!bInterss && !bInterse && !bInteres && !bInteree)
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
CFilroadConnect* CFilroadConnect::NewFilroadConnect(BOOL bAnti, CCADEntFilRoadAdatper *pEnt1, CCADEntFilRoadAdatper *pEnt2,
|
|
BOOL bStart1, BOOL bStart2, double dAngle1, double dAngle2, EPairType eType)
|
|
{
|
|
if (bAnti)
|
|
{
|
|
SWAP(pEnt1, pEnt2);
|
|
SWAP(dAngle1, dAngle2);
|
|
SWAP(bStart1, bStart2);
|
|
}
|
|
|
|
if (bStart1)
|
|
pEnt1->SetStartLink();
|
|
else
|
|
pEnt1->SetEndLink();
|
|
|
|
if (bStart2)
|
|
pEnt2->SetStartLink();
|
|
else
|
|
pEnt2->SetEndLink();
|
|
|
|
CFilroadConnect *pConnect = new CFilroadConnect(pEnt1, bStart1, pEnt2, bStart2, eType, dAngle1, dAngle2);
|
|
pConnect->InitInterPoint();
|
|
|
|
return pConnect;
|
|
}
|
|
|
|
|
|
// 创建CFilroadConnect;
|
|
BOOL CFilroadConnect::CreateConnect(CLineCADEntFilRoadAdapter* pEnt1, CLineCADEntFilRoadAdapter *pEnt2,
|
|
ArFilroadConnectPointer &arConnect)
|
|
{
|
|
ASSERT(pEnt1 != NULL);
|
|
ASSERT(pEnt2 != NULL);
|
|
|
|
ClearAcaryAll(arConnect);
|
|
BOOL bInterss, bInterse, bInteres, bInteree;
|
|
if (!TestEndPointInter(pEnt1, pEnt2, bInterss, bInterse, bInteres,bInteree, m_geTolInter))
|
|
return NULL;
|
|
|
|
BOOL bStart1 = bInterss || bInterse;
|
|
BOOL bStart2 = bInteres || bInterss;
|
|
// 由交点向另一点做延伸
|
|
double dAngle1 = bStart1 ? pEnt1->OriginSeg().direction().angle() : (-pEnt1->OriginSeg().direction()).angle();
|
|
double dAngle2 = bStart2 ? pEnt2->OriginSeg().direction().angle() : (-pEnt2->OriginSeg().direction()).angle();
|
|
|
|
if (SameAngle(dAngle1, dAngle2, m_dAngleTol))
|
|
return NULL; // 角度相同。差值为0,或者为PI*2;
|
|
if (DoubleEqual(fabs(dAngle1 - dAngle2), PI, m_dAngleTol))
|
|
return NULL; // 角度 180度。
|
|
|
|
CFilroadConnect *pConnect = NewFilroadConnect(AngleInClock(false, dAngle1, dAngle2) > PI, pEnt1, pEnt2, bStart1, bStart2,
|
|
dAngle1, dAngle2, eLine_Line);
|
|
if (pConnect != NULL)
|
|
arConnect.append(pConnect);
|
|
|
|
return !arConnect.isEmpty();
|
|
}
|
|
|
|
|
|
BOOL CFilroadConnect::CreateConnect(CLineCADEntFilRoadAdapter* pEnt1, CArcCADEntFilRoadAdapter *pEnt2,
|
|
ArFilroadConnectPointer &arConnect)
|
|
{
|
|
ASSERT(pEnt1 != NULL);
|
|
ASSERT(pEnt2 != NULL);
|
|
ClearAcaryAll(arConnect);
|
|
|
|
BOOL bInterss, bInterse, bInteres, bInteree;
|
|
if (!TestEndPointInter(pEnt1, pEnt2, bInterss, bInterse, bInteres, bInteree, m_geTolInter))
|
|
return NULL;
|
|
|
|
SEndTestConnect setc(bInterss, bInterse, bInteres, bInteree);
|
|
|
|
for (setc.Start(); !setc.End(); setc.Next())
|
|
{
|
|
BOOL bStart1, bStart2;
|
|
if (!setc.Get(bStart1, bStart2))
|
|
continue;
|
|
|
|
double dAngle1 = bStart1 ? pEnt1->OriginSeg().direction().angle() : (-pEnt1->OriginSeg().direction()).angle();
|
|
double dAngle2 = (bStart2 ? TanVecOfArcStartPoint(pEnt2->OriginSeg()) : TanVecOfArcEndPoint(pEnt2->OriginSeg())).angle();
|
|
|
|
// 直线跟圆弧相切
|
|
if (DoubleEqual(fabs(dAngle1 - dAngle2), PI, m_dAngleTol))
|
|
return NULL;
|
|
|
|
bool bAnti = false;
|
|
if (SameAngle(dAngle1, dAngle2, m_dAngleTol))
|
|
{ // 直线跟圆弧角度相同。
|
|
bool bClock = pEnt2->OriginSeg().isClockWise() ? true : false;
|
|
bClock = bStart2 ? bClock : !bClock;
|
|
|
|
if (bClock)bAnti = true;
|
|
else
|
|
bAnti = false;
|
|
}
|
|
else
|
|
{
|
|
bAnti = AngleInClock(false, dAngle1, dAngle2) > PI;
|
|
}
|
|
|
|
CFilroadConnect* pConnect = NewFilroadConnect(bAnti, pEnt1, pEnt2, bStart1, bStart2, dAngle1, dAngle2, bAnti ? eArc_Line : eLine_Arc);
|
|
if (pConnect != NULL)
|
|
arConnect.append(pConnect);
|
|
}
|
|
|
|
return !arConnect.isEmpty();
|
|
}
|
|
|
|
|
|
BOOL CFilroadConnect::CreateConnect(CArcCADEntFilRoadAdapter* pEnt1, CArcCADEntFilRoadAdapter *pEnt2,
|
|
ArFilroadConnectPointer &arConnect)
|
|
{
|
|
ASSERT(pEnt1 != NULL);
|
|
ASSERT(pEnt2 != NULL);
|
|
ClearAcaryAll(arConnect);
|
|
|
|
BOOL bInterss, bInterse, bInteres, bInteree;
|
|
if (!TestEndPointInter(pEnt1, pEnt2, bInterss, bInterse, bInteres, bInteree, m_geTolInter))
|
|
return NULL;
|
|
|
|
SEndTestConnect setc(bInterss, bInterse, bInteres, bInteree);
|
|
for (setc.Start(); !setc.End(); setc.Next())
|
|
{
|
|
BOOL bStart1, bStart2;
|
|
if (!setc.Get(bStart1, bStart2))
|
|
continue;
|
|
double dAngle1 = (bStart1 ? TanVecOfArcStartPoint(pEnt1->OriginSeg()) : TanVecOfArcEndPoint(pEnt1->OriginSeg())).angle();
|
|
double dAngle2 = (bStart2 ? TanVecOfArcStartPoint(pEnt2->OriginSeg()) : TanVecOfArcEndPoint(pEnt2->OriginSeg())).angle();
|
|
|
|
// 相切
|
|
if (DoubleEqual(fabs(dAngle1 - dAngle2), PI, m_dAngleTol))
|
|
return NULL;
|
|
|
|
bool bAnti = false;
|
|
if (SameAngle(dAngle1, dAngle2, m_dAngleTol))
|
|
{ // 直线跟圆弧角度相同。
|
|
bool bClock1 = pEnt1->OriginSeg().isClockWise() ? true : false;
|
|
bClock1 = bStart1 ? bClock1 : !bClock1; // 交点到另一点是否顺时针,或者逆时针方向
|
|
bool bClock2 = pEnt2->OriginSeg().isClockWise() ? true : false;
|
|
bClock2 = bStart2 ? bClock2 : !bClock2;
|
|
|
|
if (bClock1 == bClock2)
|
|
{
|
|
if (DoubleEqual(pEnt1->OriginSeg().radius(), pEnt2->OriginSeg().radius(), 1.0))
|
|
return NULL;
|
|
|
|
bool bBigRaidus = pEnt1->OriginSeg().radius() > pEnt2->OriginSeg().radius();
|
|
if (bClock1) // also bclock2
|
|
bAnti = bBigRaidus;
|
|
else
|
|
bAnti = !bBigRaidus;
|
|
}
|
|
else
|
|
{
|
|
if (bClock1 && !bClock2)
|
|
bAnti = false;
|
|
else
|
|
bAnti = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bAnti = AngleInClock(false, dAngle1, dAngle2) > PI;
|
|
}
|
|
|
|
CFilroadConnect *pConnect = NewFilroadConnect(bAnti, pEnt1, pEnt2, bStart1, bStart2, dAngle1, dAngle2, eArc_Arc);
|
|
if (pConnect != NULL)
|
|
arConnect.append(pConnect);
|
|
}
|
|
|
|
return !arConnect.isEmpty();
|
|
}
|
|
|
|
|
|
// 构造CFilRoadConnect.传入的参数的是以前已经倒角的边线,
|
|
BOOL CFilroadConnect::CreateConnectFilted(CLineCADEntFilRoadAdapter* pEnt1, bool bStart1,
|
|
CLineCADEntFilRoadAdapter *pEnt2, bool bStart2,
|
|
CFilroadConnect *&pConnect, CArcCADEntFilRoadAdapter* pFilArc)
|
|
{
|
|
ASSERT(pEnt1 != NULL);
|
|
ASSERT(pEnt2 != NULL);
|
|
|
|
// 由交点向另一点做延伸
|
|
double dAngle1 = bStart1 ? pEnt1->OriginSeg().direction().angle() : (-pEnt1->OriginSeg().direction()).angle();
|
|
double dAngle2 = bStart2 ? pEnt2->OriginSeg().direction().angle() : (-pEnt2->OriginSeg().direction()).angle();
|
|
|
|
if (SameAngle(dAngle1, dAngle2, m_dAngleTol))
|
|
return NULL; // 角度相同。差值为0,或者为PI*2;
|
|
if (DoubleEqual(fabs(dAngle1 - dAngle2), PI, m_dAngleTol))
|
|
return NULL; // 角度 180度。
|
|
|
|
pConnect = NewFilroadConnect(AngleInClock(false, dAngle1, dAngle2) > PI, pEnt1, pEnt2, bStart1, bStart2,
|
|
dAngle1, dAngle2, eLine_Line_Filted);
|
|
if (pConnect != NULL)
|
|
pConnect->m_pFilArc = pFilArc;
|
|
return (pConnect != NULL);
|
|
}
|
|
|
|
BOOL CFilroadConnect::CreateConnectFilted(CLineCADEntFilRoadAdapter* pEnt1, bool bStart1,
|
|
CArcCADEntFilRoadAdapter *pEnt2, bool bStart2,
|
|
CFilroadConnect *&pConnect, CArcCADEntFilRoadAdapter* pFilArc)
|
|
{
|
|
double dAngle1 = bStart1 ? pEnt1->OriginSeg().direction().angle() : (-pEnt1->OriginSeg().direction()).angle();
|
|
double dAngle2 = (bStart2 ? TanVecOfArcStartPoint(pEnt2->OriginSeg()) : TanVecOfArcEndPoint(pEnt2->OriginSeg())).angle();
|
|
|
|
// 直线跟圆弧相切
|
|
if (DoubleEqual(fabs(dAngle1 - dAngle2), PI, m_dAngleTol))
|
|
return NULL;
|
|
|
|
bool bAnti = false;
|
|
if (SameAngle(dAngle1, dAngle2, m_dAngleTol))
|
|
{ // 直线跟圆弧角度相同。
|
|
bool bClock = pEnt2->OriginSeg().isClockWise() ? true : false;
|
|
bClock = bStart2 ? bClock : !bClock;
|
|
|
|
if (bClock)bAnti = true;
|
|
else
|
|
bAnti = false;
|
|
}
|
|
else
|
|
{
|
|
bAnti = AngleInClock(false, dAngle1, dAngle2) > PI;
|
|
}
|
|
|
|
pConnect = NewFilroadConnect(bAnti, pEnt1, pEnt2, bStart1, bStart2, dAngle1, dAngle2, bAnti ? eArc_Line_Filted : eLine_Arc_Filted);
|
|
if (pConnect != NULL)
|
|
pConnect->m_pFilArc = pFilArc;
|
|
|
|
return pConnect != NULL;
|
|
}
|
|
|
|
BOOL CFilroadConnect::CreateConnectFilted(CArcCADEntFilRoadAdapter* pEnt1, bool bStart1,
|
|
CArcCADEntFilRoadAdapter *pEnt2, bool bStart2,
|
|
CFilroadConnect *&pConnect, CArcCADEntFilRoadAdapter* pFilArc)
|
|
{
|
|
// for (setc.Start(); !setc.End(); setc.Next())
|
|
{
|
|
double dAngle1 = (bStart1 ? TanVecOfArcStartPoint(pEnt1->OriginSeg()) : TanVecOfArcEndPoint(pEnt1->OriginSeg())).angle();
|
|
double dAngle2 = (bStart2 ? TanVecOfArcStartPoint(pEnt2->OriginSeg()) : TanVecOfArcEndPoint(pEnt2->OriginSeg())).angle();
|
|
|
|
// 相切
|
|
if (DoubleEqual(fabs(dAngle1 - dAngle2), PI, m_dAngleTol))
|
|
return NULL;
|
|
|
|
bool bAnti = false;
|
|
if (SameAngle(dAngle1, dAngle2, m_dAngleTol))
|
|
{ // 直线跟圆弧角度相同。
|
|
bool bClock1 = pEnt1->OriginSeg().isClockWise() ? true : false;
|
|
bClock1 = bStart1 ? bClock1 : !bClock1; // 交点到另一点是否顺时针,或者逆时针方向
|
|
bool bClock2 = pEnt2->OriginSeg().isClockWise() ? true : false;
|
|
bClock2 = bStart2 ? bClock2 : !bClock2;
|
|
|
|
if (bClock1 == bClock2)
|
|
{
|
|
if (DoubleEqual(pEnt1->OriginSeg().radius(), pEnt2->OriginSeg().radius(), 1.0))
|
|
return NULL;
|
|
|
|
bool bBigRaidus = pEnt1->OriginSeg().radius() > pEnt2->OriginSeg().radius();
|
|
if (bClock1) // also bclock2
|
|
bAnti = bBigRaidus;
|
|
else
|
|
bAnti = !bBigRaidus;
|
|
}
|
|
else
|
|
{
|
|
if (bClock1 && !bClock2)
|
|
bAnti = false;
|
|
else
|
|
bAnti = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bAnti = AngleInClock(false, dAngle1, dAngle2) > PI;
|
|
}
|
|
|
|
pConnect = NewFilroadConnect(bAnti, pEnt1, pEnt2, bStart1, bStart2, dAngle1, dAngle2, eArc_Arc_Filted);
|
|
if (pConnect != NULL)
|
|
pConnect->m_pFilArc = pFilArc;
|
|
|
|
return pConnect != NULL;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
// 检测两个roadConnect之间的关系,包括:无关,在内测,在外侧。
|
|
CFilroadConnect::ECornerRelation CFilroadConnect::CornerTo(const CFilroadConnect &otherPair) const
|
|
{
|
|
// 这种情形不能做同圆心倒角
|
|
if (m_eType != otherPair.m_eType)
|
|
return eOther;
|
|
if (SameAngle(m_dAngle1, m_dAngle2, m_dAngleTol) || SameAngle(otherPair.m_dAngle1, otherPair.m_dAngle2, m_dAngleTol))
|
|
return eOther;
|
|
|
|
// 算法检测分为两个部分:
|
|
// 1、检测两者的开口方向是否相同。
|
|
// 2、是否可以检测出明确的内外关系。
|
|
|
|
// 1/检测开口方向。
|
|
// 认为eCornerRelation覆盖一个180°的范围,本道路正好在这个180°的中间。判断两个道路是否超出对方的覆盖范围:
|
|
double dAngleRegionStart1 = StartAngleOfRegion();
|
|
double dAngleRegionStart2 = otherPair.StartAngleOfRegion();
|
|
|
|
if (AngleInRegion(dAngleRegionStart1, otherPair.m_dAngle1) &&
|
|
AngleInRegion(dAngleRegionStart1, otherPair.m_dAngle2) &&
|
|
AngleInRegion(dAngleRegionStart2, m_dAngle1) &&
|
|
AngleInRegion(dAngleRegionStart2, m_dAngle2))
|
|
{ // 开口方向一致。
|
|
|
|
// 检测内外关系:
|
|
AcGePoint2d interPt1 = AcGeLineSeg2d(otherPair.CornerPoint1(), otherPair.CornerPoint2()).midPoint();
|
|
AcGePoint2d interPt2 = AcGeLineSeg2d(this->CornerPoint1(), this->CornerPoint2()).midPoint();
|
|
|
|
// double dAngleToOther = AcGeVector2d(otherPair.InterPoint() - InterPoint()).angle();
|
|
double dAngleToOther = AcGeVector2d(interPt1 - interPt2).angle();
|
|
bool bAngleIn1 = TestAngleIn(dAngleToOther);
|
|
bool bAngleIn2 = otherPair.TestAngleIn(AntiAngle(dAngleToOther));
|
|
|
|
if (bAngleIn1 && !bAngleIn2)
|
|
{ //
|
|
return eOutCorner;
|
|
}
|
|
else if (!bAngleIn1 && bAngleIn2)
|
|
{
|
|
return eInCorner;
|
|
}
|
|
else
|
|
return eOther;
|
|
}
|
|
else
|
|
{
|
|
return eOther;
|
|
}
|
|
}
|
|
|
|
|
|
void CFilroadConnect::SetInterTol()
|
|
{
|
|
m_geTolInter.setEqualPoint(1.0);
|
|
m_geTolInter.setEqualVector(1.0);
|
|
}
|
|
|
|
AcGePoint2d CFilroadConnect::InterPoint() const
|
|
{
|
|
ASSERT(!IsFiltedConnect()); // 这种没有交点
|
|
return m_ptInter;
|
|
}
|
|
|
|
AcGePoint2d CFilroadConnect::CornerPoint1() const
|
|
{
|
|
if (m_eType == eLine_Line || m_eType == eLine_Arc || m_eType == eLine_Line_Filted || m_eType == eLine_Arc_Filted)
|
|
return m_bStart1 ? m_pEnt1->ToLineAdapter()->CurrSeg().startPoint() : m_pEnt1->ToLineAdapter()->CurrSeg().endPoint();
|
|
else
|
|
return m_bStart1 ? m_pEnt1->ToArcAdapter()->CurrSeg().startPoint() : m_pEnt1->ToArcAdapter()->CurrSeg().endPoint();
|
|
}
|
|
|
|
AcGePoint2d CFilroadConnect::CornerPoint2() const
|
|
{
|
|
if (m_eType == eLine_Line || m_eType == eArc_Line || m_eType == eLine_Line_Filted || m_eType == eArc_Line_Filted)
|
|
return m_bStart2 ? m_pEnt2->ToLineAdapter()->CurrSeg().startPoint() : m_pEnt2->ToLineAdapter()->CurrSeg().endPoint();
|
|
else
|
|
return m_bStart2 ? m_pEnt2->ToArcAdapter()->CurrSeg().startPoint() : m_pEnt2->ToArcAdapter()->CurrSeg().endPoint();
|
|
}
|
|
|
|
|
|
// 该pair所覆盖范围的起始角度
|
|
double CFilroadConnect::StartAngleOfRegion() const
|
|
{
|
|
double dAngleBetween = AngleInClock(false, m_dAngle1, m_dAngle2);
|
|
if (SameAngle(m_dAngle1, m_dAngle2, m_dAngleTol))
|
|
dAngleBetween = 0.0;
|
|
|
|
return AddAngleInClock(true, m_dAngle1, (PI - dAngleBetween)*0.5);
|
|
}
|
|
|
|
// 检测dTestAngle是否在angleRegionStart开始的180的范围内。
|
|
inline bool CFilroadConnect::AngleInRegion(double angleRegionStart, double dTestAngle)
|
|
{
|
|
return AngleInClock(false, angleRegionStart, dTestAngle) < PI;
|
|
}
|
|
|
|
bool CFilroadConnect::TestAngleIn(double dOtherAngle) const
|
|
{
|
|
if (SameAngle(m_dAngle2, m_dAngle1, m_dAngleTol))
|
|
return false;
|
|
|
|
if (SameAngle(dOtherAngle, m_dAngle1, m_dAngleTol) || SameAngle(dOtherAngle, m_dAngle2, m_dAngleTol))
|
|
return true;
|
|
else
|
|
{
|
|
double dAngleBetween = AngleInClock(false, m_dAngle1, m_dAngle2);
|
|
double dOtherAngleBetween = AngleInClock(false, m_dAngle1, dOtherAngle);
|
|
|
|
return dOtherAngleBetween < dAngleBetween;
|
|
}
|
|
}
|
|
|
|
|
|
void CFilroadConnect::InitInterPoint()
|
|
{
|
|
if (!IsFiltedConnect())
|
|
{
|
|
if (m_eType == eLine_Line || m_eType == eLine_Arc)
|
|
{
|
|
CLineCADEntFilRoadAdapter* pAdapter = (CLineCADEntFilRoadAdapter*)m_pEnt1;
|
|
m_ptInter = m_bStart1 ? pAdapter->OriginSeg().startPoint() : pAdapter->OriginSeg().endPoint();
|
|
}
|
|
else
|
|
{
|
|
CArcCADEntFilRoadAdapter* pAdapter = (CArcCADEntFilRoadAdapter*)m_pEnt1;
|
|
m_ptInter = m_bStart1 ? pAdapter->OriginSeg().startPoint() : pAdapter->OriginSeg().endPoint();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// 已经倒角的边线就不在求他们的交点
|
|
}
|
|
}
|
|
// 交点间的距离
|
|
double CFilroadConnect::DistanceTo(const CFilroadConnect &otherPair) const
|
|
{
|
|
if (!this->IsFiltedConnect() && !otherPair.IsFiltedConnect())
|
|
return this->InterPoint().distanceTo(otherPair.InterPoint());
|
|
else
|
|
{
|
|
return Minimum(2, this->CornerPoint1().distanceTo(otherPair.CornerPoint1()), this->CornerPoint2().distanceTo(otherPair.CornerPoint2()));
|
|
}
|
|
}
|
|
// 外部半径,ptInterIn,内道路的交点,dRadiusIn,内道路的倒角半径。
|
|
double CFilroadConnect::GetOutRadius(const AcGePoint2d &ptInterIn, double dRadiusIn) const
|
|
{
|
|
double dDis1, dDis2 = 0;
|
|
if ((m_eType == eLine_Line) || (m_eType == eLine_Arc))
|
|
{
|
|
dDis1 = m_pEnt1->ToLineAdapter()->OriginSeg().distanceTo(ptInterIn);
|
|
}
|
|
else if (m_eType == eArc_Arc || m_eType == eArc_Line)
|
|
{
|
|
dDis1 = m_pEnt1->ToArcAdapter()->OriginSeg().distanceTo(ptInterIn);
|
|
}
|
|
|
|
if ((m_eType == eLine_Line) || (m_eType == eArc_Line))
|
|
{
|
|
dDis2 = m_pEnt2->ToLineAdapter()->OriginSeg().distanceTo(ptInterIn);
|
|
}
|
|
else if (m_eType == eArc_Arc || m_eType == eArc_Line)
|
|
{
|
|
dDis2 = m_pEnt2->ToArcAdapter()->OriginSeg().distanceTo(ptInterIn);
|
|
}
|
|
|
|
return dRadiusIn + MAX(dDis1, dDis2);
|
|
}
|
|
|
|
// 对于已经倒过角的使用这个函数
|
|
double CFilroadConnect::GetOutRadius(const CFilroadConnect &connectIn, double dRadiusIn) const
|
|
{
|
|
double dDis1 = 0.0, dDis2 = 0.0;
|
|
|
|
if ((m_eType == eLine_Line_Filted))
|
|
{
|
|
dDis1 = m_pEnt1->ToLineAdapter()->CurrSeg().distanceTo(connectIn.m_pEnt1->ToLineAdapter()->CurrSeg());
|
|
dDis2 = m_pEnt2->ToLineAdapter()->CurrSeg().distanceTo(connectIn.m_pEnt2->ToLineAdapter()->CurrSeg());
|
|
}
|
|
else if (m_eType == eArc_Arc_Filted)
|
|
{
|
|
dDis1 = m_pEnt1->ToArcAdapter()->CurrSeg().distanceTo(connectIn.m_pEnt1->ToArcAdapter()->CurrSeg());
|
|
dDis2 = m_pEnt2->ToArcAdapter()->CurrSeg().distanceTo(connectIn.m_pEnt2->ToArcAdapter()->CurrSeg());
|
|
}
|
|
else if (m_eType == eArc_Line_Filted)
|
|
{
|
|
dDis1 = m_pEnt1->ToArcAdapter()->CurrSeg().distanceTo(connectIn.m_pEnt1->ToArcAdapter()->CurrSeg());
|
|
dDis2 = m_pEnt2->ToLineAdapter()->CurrSeg().distanceTo(connectIn.m_pEnt2->ToLineAdapter()->CurrSeg());
|
|
}
|
|
else if (m_eType == eLine_Arc_Filted)
|
|
{
|
|
dDis1 = m_pEnt1->ToLineAdapter()->CurrSeg().distanceTo(connectIn.m_pEnt1->ToLineAdapter()->CurrSeg());
|
|
dDis2 = m_pEnt2->ToArcAdapter()->CurrSeg().distanceTo(connectIn.m_pEnt2->ToArcAdapter()->CurrSeg());
|
|
}
|
|
|
|
return dRadiusIn + MAX(dDis1, dDis2);
|
|
}
|
|
|
|
|
|
// 执行倒角,
|
|
BOOL CFilroadConnect::Filroad(double dRadius, AcGeCircArc2d &arc)
|
|
{
|
|
AcGeLineSeg2d line1, line2;
|
|
AcGeCircArc2d arc1, arc2;
|
|
|
|
if(m_eType == eLine_Line || m_eType == eLine_Line_Filted)
|
|
{
|
|
line1 = m_pEnt1->ToLineAdapter()->CurrSeg();
|
|
line2 = m_pEnt2->ToLineAdapter()->CurrSeg();
|
|
|
|
if (!CRoadArith::InterCircleLineAndLine(&line1, m_bStart1 ? true : false, &line2, m_bStart2 ? true : false, dRadius, arc))
|
|
return FALSE;
|
|
else
|
|
{
|
|
m_pEnt1->ToLineAdapter()->Reset(m_bStart1, m_bStart1 ? line1.startPoint() : line1.endPoint());
|
|
m_pEnt2->ToLineAdapter()->Reset(m_bStart2, m_bStart2 ? line2.startPoint() : line2.endPoint());
|
|
if (m_eType == eLine_Line_Filted && m_pFilArc != NULL)
|
|
m_pFilArc->Erase();
|
|
}
|
|
|
|
}
|
|
else if (m_eType == eLine_Arc || m_eType == eLine_Arc_Filted)
|
|
{
|
|
line1 = m_pEnt1->ToLineAdapter()->CurrSeg();
|
|
arc2 = m_pEnt2->ToArcAdapter()->CurrSeg();
|
|
|
|
if (!CRoadArith::InterCircleLineAndArc(&line1, m_bStart1 ? true : false, &arc2, m_bStart2 ? true : false, dRadius, arc))
|
|
return FALSE;
|
|
else
|
|
{
|
|
m_pEnt1->ToLineAdapter()->Reset(m_bStart1, m_bStart1 ? line1.startPoint() : line1.endPoint());
|
|
m_pEnt2->ToArcAdapter()->Reset(m_bStart2, m_bStart2 ? arc2.startPoint() : arc2.endPoint());
|
|
if (m_eType == eLine_Arc_Filted && m_pFilArc != NULL)
|
|
m_pFilArc->Erase();
|
|
}
|
|
}
|
|
else if (m_eType == eArc_Line || m_eType == eArc_Line_Filted)
|
|
{
|
|
arc1 = m_pEnt1->ToArcAdapter()->CurrSeg();
|
|
line2 = m_pEnt2->ToLineAdapter()->CurrSeg();
|
|
|
|
if (!CRoadArith::InterCircleArcAndLine(&arc1, m_bStart1 ? true : false, &line2, m_bStart2 ? true : false, dRadius, arc))
|
|
return FALSE;
|
|
else
|
|
{
|
|
m_pEnt1->ToArcAdapter()->Reset(m_bStart1, m_bStart1 ? arc1.startPoint() : arc1.endPoint());
|
|
m_pEnt2->ToLineAdapter()->Reset(m_bStart2, m_bStart2 ? line2.startPoint() : line2.endPoint());
|
|
if (m_eType == eArc_Line_Filted && m_pFilArc != NULL)
|
|
m_pFilArc->Erase();
|
|
}
|
|
}
|
|
else if (m_eType == eArc_Arc || m_eType == eArc_Arc_Filted)
|
|
{
|
|
arc1 = m_pEnt1->ToArcAdapter()->CurrSeg();
|
|
arc2 = m_pEnt2->ToArcAdapter()->CurrSeg();
|
|
|
|
if (!CRoadArith::InterCircleArcAndArc(&arc1, m_bStart1 ? true : false, &arc2, m_bStart2 ? true : false, dRadius, arc))
|
|
return FALSE;
|
|
else
|
|
{
|
|
m_pEnt1->ToArcAdapter()->Reset(m_bStart1, m_bStart1 ? arc1.startPoint() : arc1.endPoint());
|
|
m_pEnt2->ToArcAdapter()->Reset(m_bStart2, m_bStart2 ? arc2.startPoint() : arc2.endPoint());
|
|
if (m_eType == eArc_Arc_Filted && m_pFilArc != NULL)
|
|
m_pFilArc->Erase();
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// 对外侧执行倒角
|
|
BOOL CFilroadConnect::Filroad(const CFilroadConnect &filConnect, double dRadiusIn, AcGeCircArc2d &arcFil)
|
|
{
|
|
if (this->IsFiltedConnect() && filConnect.IsFiltedConnect())
|
|
{ // 都是已经倒角的数据
|
|
return Filroad(GetOutRadius(filConnect, dRadiusIn), arcFil);
|
|
}
|
|
else if (!this->IsFiltedConnect() && !filConnect.IsFiltedConnect())
|
|
{
|
|
return Filroad(GetOutRadius(filConnect.InterPoint(), dRadiusIn), arcFil);
|
|
}
|
|
else
|
|
{ // 自己搞吧
|
|
return Filroad(dRadiusIn, arcFil);
|
|
}
|
|
}
|