1252 lines
26 KiB
C++
1252 lines
26 KiB
C++
//-----------------------------------------------------------------------------+
|
|
// Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd.
|
|
// = FileName : TGGeCurveSegment 类
|
|
// = Version : ver2.0
|
|
// = Author : wlw
|
|
// = CreateDate : 2002-09-09
|
|
// = Description: TGGeCurveSegment 类定义
|
|
// = Maintainers:
|
|
//
|
|
//-----------------------------------------------------------------------------+
|
|
#include "StdAfx.h"
|
|
#include "TGGeCurveSegment.h"
|
|
#include "TAcDbObjectPtr.h"
|
|
#include "TchGlobalCurveFunc.h"
|
|
#include "TchPrivateGlobalFunc.h"
|
|
#include "TGGeCurveInline.h"
|
|
#include "TchGlobalFunc.h"
|
|
|
|
|
|
TGGeCurveSegment::TGGeCurveSegment(int flg)
|
|
: TGGeLine(flg),m_dBulge(0.0)
|
|
{
|
|
|
|
}
|
|
|
|
TGGeCurveSegment::TGGeCurveSegment(const TEntitySet &e, int flg)
|
|
: TGGeLine(flg),m_dBulge(0.0)
|
|
{
|
|
TAcDbObjectPtr obj(e.name, AcDb::kForRead, Adesk::kTrue);
|
|
if (!obj)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (obj.m_pObject->isKindOf(AcDbLine::desc()))
|
|
{
|
|
AcDbLine *pLine = (AcDbLine *)obj.m_pObject;
|
|
|
|
m_startPoint = pLine->startPoint();
|
|
m_endPoint = pLine->endPoint();
|
|
}
|
|
else if (obj.m_pObject->isKindOf(AcDbArc::desc()))
|
|
{
|
|
AcDbArc *pLine = (AcDbArc *)obj.m_pObject;
|
|
|
|
TADSGePoint3d ptCen;
|
|
(AcGePoint3d &)ptCen = pLine->center();
|
|
|
|
TVector3D vtNormal;
|
|
(AcGeVector3d &)vtNormal = pLine->normal();
|
|
|
|
ptCen = TchPrivate::Wcs2Ecs(ptCen, vtNormal);
|
|
|
|
TGGeArc arc(ptCen, pLine->radius(), pLine->startAngle(), pLine->endAngle());
|
|
|
|
m_nFlag = LS_FINITE;
|
|
|
|
ads_polar(arc.GetCenterPt(), arc.GetStarAngle(), arc.GetRadius(), m_startPoint);
|
|
ads_polar(arc.GetCenterPt(), arc.GetEndAngle(), arc.GetRadius(), m_endPoint);
|
|
|
|
m_dBulge = arc.Bulge();
|
|
}
|
|
else if (obj.m_pObject->isKindOf(AcDbCircle::desc()))
|
|
{
|
|
AcDbCircle *pLine = (AcDbCircle *)obj.m_pObject;
|
|
|
|
TADSGePoint3d ptCen;
|
|
(AcGePoint3d &)ptCen = pLine->center();
|
|
|
|
TVector3D vtNormal;
|
|
(AcGeVector3d &)vtNormal = pLine->normal();
|
|
|
|
ptCen = TchPrivate::Wcs2Ecs(ptCen, vtNormal);
|
|
|
|
ads_polar(ptCen, 0.0, pLine->radius(), m_startPoint);
|
|
ads_polar(ptCen, PI, pLine->radius(), m_endPoint);
|
|
|
|
m_dBulge = PI*2.0;
|
|
}
|
|
}
|
|
|
|
TGGeCurveSegment::TGGeCurveSegment(const TADSGePoint3d &spt, const TADSGePoint3d &ept, ads_real ang, int flg)
|
|
: TGGeLine(spt,ept,flg)
|
|
{
|
|
m_dBulge = ang;
|
|
}
|
|
|
|
TGGeCurveSegment::TGGeCurveSegment(const TGGeCurveSegment &src)
|
|
: TGGeLine(LS_FINITE)
|
|
{
|
|
m_startPoint = src.m_startPoint;
|
|
m_endPoint = src.m_endPoint;
|
|
m_dBulge = src.m_dBulge;
|
|
m_nFlag = src.m_nFlag;
|
|
}
|
|
|
|
TGGeCurveSegment::~TGGeCurveSegment()
|
|
{
|
|
|
|
}
|
|
|
|
//lfy 2010-08-31 增加line,arc的set函数
|
|
TGGeCurveSegment & TGGeCurveSegment::SetLine(const TADSGePoint3d& pt1, const TADSGePoint3d& pt2)
|
|
{
|
|
m_nFlag = LS_INFINITE;
|
|
m_startPoint = pt1;
|
|
m_endPoint = pt2;
|
|
m_dBulge = 0.0;
|
|
return *this;
|
|
}
|
|
|
|
TGGeCurveSegment & TGGeCurveSegment:: SetArc(const TADSGePoint3d &spt, const TADSGePoint3d &ept, ads_real dang)
|
|
{
|
|
ads_real ddis = ads_distance(spt, ept) / 2.0;
|
|
ads_real dangTmp = fabs(dang / 2.0);
|
|
ads_real dRadius = ddis / sin(dangTmp);
|
|
ads_real dcosr = fabs( dRadius * cos(dangTmp));
|
|
ads_real dstartAngle = 0.0,dendAngle = 0.0;
|
|
|
|
TADSGePoint3d ptc1, ptc2, mpt,ptCenter;
|
|
mpt = spt + ept;
|
|
mpt.Scale(0.5);
|
|
|
|
ads_polar(mpt, ads_angle(spt, ept) - PI / 2.0, dcosr, ptc1);
|
|
ads_polar(mpt, ads_angle(spt, ept) + PI / 2.0, dcosr, ptc2);
|
|
|
|
if (dang > 0)
|
|
{
|
|
if (fabs(dang) > PI)
|
|
{
|
|
ptCenter = ptc1;
|
|
}
|
|
else
|
|
{
|
|
ptCenter = ptc2;
|
|
}
|
|
|
|
dstartAngle = ads_angle(ptCenter, spt);
|
|
dendAngle = ads_angle(ptCenter, ept);
|
|
}
|
|
else
|
|
{
|
|
if (fabs(dang) > PI)
|
|
{
|
|
ptCenter = ptc2;
|
|
}
|
|
else
|
|
{
|
|
ptCenter = ptc1;
|
|
}
|
|
|
|
dstartAngle = ads_angle(ptCenter, ept);
|
|
dendAngle = ads_angle(ptCenter, spt);
|
|
}
|
|
|
|
m_nFlag = LS_INFINITE;
|
|
|
|
ads_polar(ptCenter,dstartAngle, dRadius, m_startPoint);
|
|
ads_polar(ptCenter,dendAngle, dRadius, m_endPoint);
|
|
|
|
m_dBulge = dendAngle - dstartAngle;
|
|
if (m_dBulge < -1E-6)
|
|
{
|
|
m_dBulge = 2.0 * PI + m_dBulge;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
TGGeCurveSegment & TGGeCurveSegment::SetCircle(const TADSGePoint3d& ptCen,double dRadius)
|
|
{
|
|
ads_polar(ptCen, 0.0, dRadius, m_startPoint);
|
|
ads_polar(ptCen, PI, dRadius, m_endPoint);
|
|
m_dBulge = 2.0 * PI;
|
|
return *this;
|
|
}
|
|
|
|
AcDbCurve * TGGeCurveSegment::AsAcDbCurve() const
|
|
{
|
|
AcDbCurve *pCurve = NULL;
|
|
if (Is(CURVE_LINE))
|
|
{
|
|
pCurve = new AcDbLine(m_startPoint, m_endPoint);
|
|
}
|
|
else if (Is(CURVE_ARC))
|
|
{
|
|
TGGeArc ar = GetArc();
|
|
pCurve = new AcDbArc(ar.GetCenterPt(), ar.GetRadius(), ar.GetStarAngle(), ar.GetEndAngle());
|
|
}
|
|
return pCurve;
|
|
}
|
|
|
|
resbuf *TGGeCurveSegment::Mask(LPCTSTR pszLay)
|
|
{
|
|
TCString sLayer = pszLay? pszLay : _T("*");
|
|
return ads_buildlist( -4, _T("<or"),
|
|
RTDXF0,_T("LINE"), RTDXF0, _T("ARC"), RTDXF0,_T("CIRCLE"),
|
|
-4, _T("or>"), 8, (LPCTSTR)sLayer, NULL);
|
|
}
|
|
|
|
int TGGeCurveSegment::MakeArrow(TEntitySet &res) const
|
|
{
|
|
ads_point cpt, pt1, pt2, pt3;
|
|
ads_real arrowWidth = 200,
|
|
arrowWidthFactor = 5.0;
|
|
TADSGePoint3d mpt = MidPoint();
|
|
ads_real drt = Direction(mpt);
|
|
|
|
ads_polar(mpt, drt - PI, arrowWidth * arrowWidthFactor / 2.0, cpt);
|
|
ads_polar(cpt, drt + PI / 2.0, arrowWidth / 2.0, pt1);
|
|
ads_polar(cpt, drt - PI / 2.0, arrowWidth / 2.0, pt2);
|
|
ads_polar(mpt, drt, arrowWidth * arrowWidthFactor / 2.0, pt3);
|
|
|
|
return res.Make(RTDXF0, _T("SOLID"), 10, pt1, 11, pt2, 12, pt3, 13, pt3, NULL);
|
|
}
|
|
|
|
// 积分面积
|
|
ads_real TGGeCurveSegment::PathArea(TADSGePoint3d &spt) const
|
|
{
|
|
spt.z = GetStartPoint().z;
|
|
TADSGePoint3d ept = (spt.Distance(m_startPoint) <
|
|
spt.Distance(m_endPoint)) ?
|
|
m_endPoint :
|
|
m_startPoint;
|
|
|
|
ads_real result;
|
|
if (Is(CURVE_LINE))
|
|
{
|
|
result = (ept.x - spt.x) * (spt.y + ept.y) / 2.0;
|
|
}
|
|
else if (Is(CURVE_ARC))
|
|
{
|
|
result = GetArc().PathArea();
|
|
// 顺时针的弧
|
|
if (spt.Distance2d(m_startPoint) > spt.Distance2d(m_endPoint))
|
|
{
|
|
result = 0.0 - result;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
result = GetCircle().Area();
|
|
}
|
|
|
|
spt = ept;
|
|
return result;
|
|
}
|
|
|
|
// 点到自身的距离, 负数为内/左侧
|
|
double TGGeCurveSegment::GetDist2Me(TADSGePoint3d ptMid) const
|
|
{
|
|
TADSGePoint3d ptPrj;
|
|
ProjectToMe(ptMid, ptPrj);
|
|
|
|
int nSide = OnWhichSide(ptMid);
|
|
double nDist = ptMid.Distance2d(ptPrj);
|
|
return (nSide == OFFSET_LEFT ? -nDist : nDist);
|
|
}
|
|
|
|
// 取得一段子曲线
|
|
// loc -- center of the subCurve
|
|
// chordLen -- 子曲线弦长
|
|
// res -- 结果子曲线
|
|
// return: RTNORM--OK; RTERROR--fail
|
|
int TGGeCurveSegment::GetSubSegment(const TADSGePoint3d &ptloc, ads_real dchordLen, TGGeCurveSegment &res) const
|
|
{
|
|
//lfy 2010-08-31 修改了部分值调用
|
|
res.SetBulge(GetBulge());
|
|
res.SetLineFlag(LS_FINITE);
|
|
|
|
int rc = RTERROR;
|
|
if (Is(CURVE_LINE))
|
|
{
|
|
rc = GetLine().GetSubLine(ptloc, dchordLen, res);
|
|
}
|
|
else if (Is(CURVE_ARC))
|
|
{
|
|
TGGeArc arc1 = GetArc(), arc;
|
|
if (m_nFlag == LS_INFINITE)
|
|
{
|
|
rc = TGGeCircle(arc1.m_ptCenter, arc1.m_dRadius).GetSubArc(ptloc, dchordLen, arc);
|
|
}
|
|
else
|
|
{
|
|
rc = arc1.GetSubArc(ptloc, dchordLen, arc);
|
|
}
|
|
|
|
if (rc == RTNORM)
|
|
{
|
|
TADSGePoint3d ptStart = res.StartPoint();
|
|
TADSGePoint3d ptEnd = res.EndPoint();
|
|
|
|
ads_polar(arc.m_ptCenter, arc.m_dstartAngle,arc.m_dRadius, ptStart);
|
|
ads_polar(arc.m_ptCenter, arc.m_dendAngle, arc.m_dRadius, ptEnd);
|
|
|
|
res.SetStartPoint(ptStart);
|
|
res.SetEndPoint(ptEnd);
|
|
|
|
res.SetBulge(arc.Bulge());
|
|
}
|
|
}
|
|
else if (Is(CURVE_CIRCLE))
|
|
{
|
|
TGGeArc arc;
|
|
rc = GetCircle().GetSubArc(ptloc, dchordLen, arc);
|
|
if (rc == RTNORM)
|
|
{
|
|
TADSGePoint3d ptStart = res.StartPoint(),
|
|
ptEnd = res.EndPoint();
|
|
|
|
ads_polar(arc.m_ptCenter, arc.m_dstartAngle, arc.m_dRadius, ptStart);
|
|
ads_polar(arc.m_ptCenter, arc.m_dendAngle, arc.m_dRadius, ptEnd);
|
|
|
|
res.SetStartPoint(ptStart);
|
|
res.SetEndPoint(ptEnd);
|
|
|
|
res.SetBulge(arc.Bulge());
|
|
}
|
|
}
|
|
return rc;
|
|
}
|
|
|
|
TADSGePoint3d TGGeCurveSegment::MidPoint() const
|
|
{
|
|
TADSGePoint3d mpt;
|
|
if (Is(CURVE_LINE))
|
|
{
|
|
mpt = TGGeLine::MidPoint();
|
|
}
|
|
else if (Is(CURVE_ARC))
|
|
{
|
|
GetArc().MidPoint(mpt);
|
|
}
|
|
else
|
|
{
|
|
return GetStartPoint();
|
|
}
|
|
|
|
return mpt;
|
|
}
|
|
|
|
ads_real TGGeCurveSegment::GetLength() const
|
|
{
|
|
if (Is(CURVE_LINE))
|
|
{
|
|
return TGGeLine::GetLength();
|
|
}
|
|
else if (Is(CURVE_ARC))
|
|
{
|
|
return GetArc().GetLength();
|
|
}
|
|
else
|
|
{
|
|
return GetCircle().GetLength();
|
|
}
|
|
}
|
|
|
|
void TGGeCurveSegment::SetPoints(const TADSGePoint3d &ptStart, const TADSGePoint3d &ptEnd)
|
|
{
|
|
assert(!Is(CURVE_CIRCLE));
|
|
if (Is(CURVE_ARC))
|
|
{
|
|
TGGeArc ar = GetArc();
|
|
ar.SetAngleByPoints(ptStart, ptEnd);
|
|
|
|
*this = ar;
|
|
}
|
|
else
|
|
{
|
|
//TGGeLine::SetPoints(ptStart, ptEnd);
|
|
m_startPoint = ptStart;
|
|
m_endPoint = ptEnd;
|
|
}
|
|
}
|
|
|
|
|
|
TGGeCircle TGGeCurveSegment::GetCircle() const
|
|
{
|
|
return TGGeCircle(m_startPoint, m_endPoint);
|
|
}
|
|
|
|
TGGeArc TGGeCurveSegment::GetArc() const
|
|
{
|
|
return TGGeArc(m_startPoint, m_endPoint, m_dBulge);
|
|
}
|
|
|
|
int TGGeCurveSegment::Intersection(const TGGeCurveSegment& curve, ads_point pt1, ads_point pt2) const
|
|
{
|
|
if (curve.Is(CURVE_LINE))
|
|
{
|
|
return Intersection(curve.GetLine(), pt1, pt2);
|
|
}
|
|
else if (curve.Is(CURVE_ARC))
|
|
{
|
|
TGGeArc aArc = curve.GetArc();
|
|
if (curve.GetLineFlag() == LS_INFINITE)
|
|
{
|
|
TGGeCircle aCir = aArc;
|
|
int rc = Intersection(&aCir, pt1, pt2);
|
|
return rc;
|
|
}
|
|
else
|
|
{
|
|
return Intersection(&aArc, pt1, pt2);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TGGeCircle cir(curve.GetCircle());
|
|
return Intersection(&cir, pt1, pt2);
|
|
}
|
|
}
|
|
|
|
int TGGeCurveSegment::Intersection(const TGGeLine& line, ads_point pt1, ads_point pt2) const
|
|
{
|
|
if(Is(CURVE_LINE))
|
|
{
|
|
return GetLine().Intersection(&line, pt1);
|
|
}
|
|
else if(Is(CURVE_ARC))
|
|
{
|
|
TGGeArc aArc = GetArc();
|
|
if(m_nFlag == LS_FINITE)
|
|
{
|
|
return aArc.Intersection(&line, pt1, pt2);
|
|
}
|
|
|
|
TGGeCircle aCir = aArc;
|
|
int rc = aCir.Intersection(&line, pt1, pt2);
|
|
return rc;
|
|
}
|
|
else
|
|
{
|
|
return GetCircle().Intersection(&line, pt1, pt2);
|
|
}
|
|
}
|
|
|
|
int TGGeCurveSegment::Intersection(const TGGeArc* pArc, ads_point pt1, ads_point pt2) const
|
|
{
|
|
if (Is(CURVE_LINE))
|
|
{
|
|
return GetLine().Intersection(pArc, pt1,pt2);
|
|
}
|
|
else if (Is(CURVE_ARC))
|
|
{
|
|
TGGeArc aArc = GetArc();
|
|
if (m_nFlag == LS_FINITE)
|
|
{
|
|
return aArc.Intersection(pArc, pt1, pt2);
|
|
}
|
|
|
|
TGGeCircle aCir = aArc;
|
|
int rc = aCir.Intersection(pArc, pt1, pt2);
|
|
return rc;
|
|
}
|
|
else
|
|
{
|
|
return GetCircle().Intersection(pArc, pt1, pt2);
|
|
}
|
|
}
|
|
|
|
int TGGeCurveSegment::Intersection(const TGGeCircle* pCir, ads_point pt1, ads_point pt2) const
|
|
{
|
|
if (Is(CURVE_LINE))
|
|
{
|
|
return GetLine().Intersection(pCir, pt1,pt2);
|
|
}
|
|
else if (Is(CURVE_ARC))
|
|
{
|
|
TGGeArc aArc = GetArc();
|
|
if (m_nFlag == LS_FINITE)
|
|
{
|
|
return aArc.Intersection(pCir, pt1, pt2);
|
|
}
|
|
|
|
TGGeCircle aCir = aArc;
|
|
int rc = aCir.Intersection(pCir, pt1, pt2);
|
|
return rc;
|
|
}
|
|
else
|
|
{
|
|
return GetCircle().Intersection(pCir, pt1, pt2);
|
|
}
|
|
}
|
|
|
|
int TGGeCurveSegment::ProjectToMe(const TADSGePoint3d &src, TADSGePoint3d &res) const
|
|
{
|
|
//lfy 2010-08-31 下面两句似乎无用
|
|
/*TADSGePoint3d src1 = src;
|
|
src1.z = GetStartPoint().z;*/
|
|
|
|
if (Is(CURVE_LINE))
|
|
{
|
|
return PointProjectToLine(src, m_startPoint, m_endPoint, res);
|
|
}
|
|
else if (Is(CURVE_ARC))
|
|
{
|
|
TGGeArc arc(GetArc());
|
|
return src.Project(&arc, res);
|
|
}
|
|
else
|
|
{
|
|
|
|
TGGeCircle cir(GetCircle());
|
|
return src.Project(&cir, res);
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int TGGeCurveSegment::Make(const TCHAR *pszLay) const
|
|
{
|
|
if (Is(CURVE_LINE))
|
|
{
|
|
TGGeLine::Make(pszLay);
|
|
}
|
|
else if (Is(CURVE_ARC))
|
|
{
|
|
GetArc().Make(pszLay);
|
|
}
|
|
else
|
|
{
|
|
GetCircle().Make(pszLay);
|
|
}
|
|
|
|
return RTNORM;
|
|
}
|
|
|
|
int TGGeCurveSegment::OSnap(int nMode, TADSGePoint3d &ptPick) const
|
|
{
|
|
if (Is(CURVE_LINE))
|
|
{
|
|
return TGGeLine::OSnap(nMode, ptPick);
|
|
}
|
|
else if (Is(CURVE_ARC))
|
|
{
|
|
return GetArc().OSnap(nMode, ptPick);
|
|
}
|
|
else if (Is(CURVE_CIRCLE))
|
|
{
|
|
return GetCircle().OSnap(nMode, ptPick);
|
|
}
|
|
|
|
return OS_NON;
|
|
}
|
|
|
|
// 把曲线化作Poly2D
|
|
void TGGeCurveSegment::AsPoly2D(TGGePoly2D &poly) const
|
|
{
|
|
//用两个弧来近似
|
|
if (Is(CURVE_CIRCLE))
|
|
{
|
|
poly.AppendPointListAt(new TADSGePoint3d(m_startPoint));
|
|
poly.AppendBugle(PI);
|
|
poly.AppendPointListAt(new TADSGePoint3d(m_endPoint));
|
|
poly.AppendBugle(PI);
|
|
poly.SetFlag(1);
|
|
|
|
}
|
|
else
|
|
{
|
|
poly.AppendPointListAt(new TADSGePoint3d(m_startPoint));
|
|
poly.AppendBugle(m_dBulge);
|
|
poly.AppendPointListAt(new TADSGePoint3d(m_endPoint));
|
|
poly.AppendBugle(0.0);
|
|
poly.SetFlag(0);
|
|
}
|
|
}
|
|
|
|
// 把曲线化作篱笆
|
|
resbuf * TGGeCurveSegment::AsFence(int nCirDiv) const
|
|
{
|
|
TGGePoly2D poly(0);
|
|
AsPoly2D(poly);
|
|
|
|
return poly.Fence();
|
|
}
|
|
|
|
ads_real TGGeCurveSegment::IDirection(int npt) const
|
|
{
|
|
ads_real result;
|
|
if (Is(CURVE_LINE))
|
|
{
|
|
result = npt ? RevDrtAngle(TGGeLine::Direction()) : TGGeLine::Direction();
|
|
}
|
|
else if (Is(CURVE_ARC))
|
|
{
|
|
TGGeArc aArc(m_startPoint, m_endPoint, m_dBulge);
|
|
result = aArc.IDirection(npt);
|
|
}
|
|
else
|
|
{
|
|
TchGeLib::adsout << _T("\nInvalid Call to IDirection() for Circle!");
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
ads_real TGGeCurveSegment::Direction(const TADSGePoint3d &pt) const
|
|
{
|
|
//lfy 2010-08-31 修改值传递
|
|
TADSGePoint3d cpt;
|
|
if (Is(CURVE_LINE))
|
|
{
|
|
return TGGeLine::Direction();
|
|
}
|
|
else if (Is(CURVE_ARC))
|
|
{
|
|
cpt = GetArc().m_ptCenter;
|
|
}
|
|
else
|
|
{
|
|
cpt = GetCircle().m_ptCenter;
|
|
}
|
|
|
|
return AngleRangeTo2PI(ads_angle(cpt, pt) + PI / 2.0);
|
|
}
|
|
|
|
// 求通过pt点的法向
|
|
ads_real TGGeCurveSegment::OrthoDirection(const TADSGePoint3d &pt) const
|
|
{
|
|
return AngleRangeTo2PI(TGGeCurveSegment::Direction(pt) - PI / 2.0);
|
|
}
|
|
|
|
// Following should move to TGGeCurveSegment
|
|
// 从端点开始沿曲线走过给定距离的点向量
|
|
int TGGeCurveSegment::Polar(ads_real dDist, TADSGePointDir2d &ptres, int bFromStart) const
|
|
{
|
|
//lfy 2010-08-31 修改值传递
|
|
if (Is(CURVE_CIRCLE))
|
|
{
|
|
return RTERROR;
|
|
}
|
|
|
|
int bIsLine = Is(CURVE_LINE);
|
|
if (bIsLine)
|
|
{
|
|
ads_real nDrt = bFromStart ? TGGeLine::Direction() : AngleRangeTo2PI(TGGeLine::Direction() + PI);
|
|
ads_polar(bFromStart ? m_startPoint : m_endPoint, nDrt, dDist, ptres);
|
|
ptres.nDirection = dDist > -1.0E-9 ? nDrt : AngleRangeTo2PI(nDrt + PI);
|
|
}
|
|
else
|
|
{
|
|
TGGeArc arc = GetArc();
|
|
ads_real nAcrossAngle = dDist / arc.m_dRadius;
|
|
if (!bFromStart)
|
|
{
|
|
nAcrossAngle = -nAcrossAngle;
|
|
}
|
|
|
|
ads_real nPositionAngle = AngleRangeTo2PI((bFromStart ? arc.m_dstartAngle : arc.m_dendAngle) + nAcrossAngle);
|
|
ads_polar(arc.m_ptCenter, nPositionAngle, arc.m_dRadius, ptres);
|
|
|
|
int nFactor = (dDist > -1.0E-9 ? 1 : -1) * (bFromStart ? 1 : -1);
|
|
if (nFactor < 0)
|
|
{
|
|
nFactor = 1;
|
|
}
|
|
else
|
|
{
|
|
nFactor = 0;
|
|
}
|
|
|
|
ptres.nDirection = AngleRangeTo2PI(nPositionAngle + PI / 2.0 + nFactor * PI);
|
|
}
|
|
|
|
return RTNORM;
|
|
}
|
|
|
|
// 求到端点的沿曲线线位移, 在线内距离为正,否则为负, 和Polar配合使用
|
|
// pt如果不在线上的话则先投影
|
|
// Note: 不能用于CIRCLE
|
|
ads_real TGGeCurveSegment::PathDistance(const TADSGePoint3d &pt, int bFromStart) const
|
|
{
|
|
assert(!Is(CURVE_CIRCLE));
|
|
|
|
TADSGePoint3d ptOnBase;
|
|
ProjectToMe(pt, ptOnBase);
|
|
|
|
const TGGeCurveSegment &thisCurve = *this;
|
|
int nPrFlag = ptOnBase & thisCurve;
|
|
const TADSGePoint3d &ptEnd = bFromStart ? m_startPoint : m_endPoint;
|
|
const TADSGePoint3d &ptOther = bFromStart ? m_endPoint : m_startPoint;
|
|
|
|
switch(nPrFlag)
|
|
{
|
|
case PR_ONPT1:
|
|
return bFromStart ? 0.0 : thisCurve.GetLength();
|
|
case PR_ONPT2:
|
|
return bFromStart ? thisCurve.GetLength() : 0.0;
|
|
case PR_INSIDE:
|
|
if (Is(CURVE_LINE))
|
|
{
|
|
return ads_distance(ptEnd, ptOnBase);
|
|
}
|
|
else
|
|
{
|
|
TGGeArc ar = GetArc();
|
|
|
|
if (bFromStart)
|
|
{
|
|
ar.SetEndAngle(ads_angle(ar.m_ptCenter, ptOnBase));
|
|
}
|
|
else
|
|
{
|
|
ar.SetStarAngle(ads_angle(ar.m_ptCenter, ptOnBase));
|
|
}
|
|
|
|
return ar.GetLength();
|
|
}
|
|
case PR_EXTEND:
|
|
case PR_OUTSIDE: // 原先不正确, 在线段之外, 并不一定为负
|
|
if (Is(CURVE_LINE))
|
|
{
|
|
ads_real nDist = ads_distance(ptEnd, ptOnBase);
|
|
ads_real nDist1 = ads_distance(ptOther, ptOnBase);
|
|
if (nDist < nDist1) // 在靠近ptEnd的延长线上,
|
|
{
|
|
return -nDist;
|
|
}
|
|
else
|
|
{
|
|
return nDist;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TGGeArc ar = GetArc();
|
|
//TGGeArc ar = arc;
|
|
|
|
if (bFromStart)
|
|
{
|
|
ar.SetEndAngle(ads_angle(ar.m_ptCenter, ptOnBase));
|
|
}
|
|
else
|
|
{
|
|
ar.SetStarAngle(ads_angle(ar.m_ptCenter, ptOnBase));
|
|
}
|
|
|
|
double dAngleS = ar.m_dstartAngle;
|
|
double dAngleE = ar.m_dendAngle;
|
|
|
|
//TchPrivate::Exchange(ar.GetStarAngle(), ar.GetEndAngle()); wulw
|
|
ar.SetStarAngle(dAngleE);
|
|
ar.SetEndAngle(dAngleS);
|
|
return -ar.GetLength();
|
|
}
|
|
}
|
|
return 0.0;
|
|
}
|
|
|
|
bool TGGeCurveSegment::IsDirectionCurve()
|
|
{
|
|
return false;
|
|
}
|
|
|
|
TGGeCurveSegment TGGeCurveSegment::Offset(double dDist, int nflg) const
|
|
{
|
|
return Offset(OFFSET_RIGHT, dDist, nflg);
|
|
}
|
|
|
|
// lr-- 0:逆时针,左侧; 1:顺时针,右侧
|
|
TGGeCurveSegment TGGeCurveSegment::Offset(int nlr, ads_real dDist, int nflg) const
|
|
{
|
|
//lfy 2008-08-31 修改值传递
|
|
ads_real ang = nlr ? -PI / 2.0 : PI / 2.0; //右:顺时针;左:逆时针
|
|
TADSGePoint3d spt, ept;
|
|
if (Is(CURVE_LINE))
|
|
{
|
|
ang = AngleRangeTo2PI(TGGeLine::Direction() + ang);
|
|
ads_polar(m_startPoint, ang, dDist, spt);
|
|
ads_polar(m_endPoint, ang, dDist, ept);
|
|
}
|
|
else
|
|
{
|
|
ads_real ang = m_dBulge;
|
|
if (Is(CURVE_CIRCLE))
|
|
{
|
|
ang = PI;
|
|
}
|
|
|
|
TGGeArc aArc(m_startPoint, m_endPoint, ang);
|
|
ads_real r = nlr ? (aArc.m_dRadius + dDist) : (aArc.m_dRadius - dDist);
|
|
if (r < _DIST_SNAP)
|
|
{
|
|
spt = aArc.m_ptCenter;
|
|
ept = aArc.m_ptCenter;
|
|
}
|
|
else
|
|
{
|
|
ads_polar(aArc.m_ptCenter, aArc.m_dstartAngle, r, spt);
|
|
ads_polar(aArc.m_ptCenter, aArc.m_dendAngle, r, ept);
|
|
}
|
|
}
|
|
|
|
return TGGeCurveSegment(spt, ept, m_dBulge, nflg);
|
|
}
|
|
|
|
void TGGeCurveSegment::TransformBy(ads_matrix mat)
|
|
{
|
|
if (Is(CURVE_LINE))
|
|
{
|
|
m_startPoint.TransformBy(mat);
|
|
m_endPoint.TransformBy(mat);
|
|
}
|
|
else if (Is(CURVE_ARC))
|
|
{
|
|
TADSGePoint3d ptMid = MidPoint();
|
|
|
|
m_startPoint.TransformBy(mat);
|
|
m_endPoint.TransformBy(mat);
|
|
ptMid.TransformBy(mat);
|
|
|
|
(TGGeCurveSegment &)(*this) = TGGeArc(m_startPoint, ptMid, m_endPoint);
|
|
|
|
}
|
|
}
|
|
|
|
int TGGeCurveSegment::OnWhichSide1(const TADSGePoint3d &src) const
|
|
{
|
|
int nSideFlag = 2;
|
|
|
|
TADSGePoint3d ptOnMe;
|
|
if (ProjectToMe(src, ptOnMe) != RTNORM)
|
|
{
|
|
nSideFlag = 2;
|
|
}
|
|
else
|
|
{
|
|
TADSGePoint3d src1 = src;
|
|
src1.z = m_startPoint.z;
|
|
if (src1 == ptOnMe)
|
|
{
|
|
nSideFlag = 2;
|
|
}
|
|
else
|
|
{
|
|
double nDir1 = Direction(ptOnMe);
|
|
double nDir2 = AngleRangeTo2PI(ads_angle(src1, ptOnMe) + PI / 2.0);
|
|
|
|
if (IsExactSameDrt(nDir1, nDir2, _angSnap))
|
|
{
|
|
nSideFlag = OFFSET_LEFT;
|
|
}
|
|
else
|
|
{
|
|
nSideFlag = OFFSET_RIGHT;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (Is(CURVE_ARC))
|
|
{
|
|
int nSideFlag0 = TGGeLine::OnWhichSide(src);
|
|
if (nSideFlag0 == OFFSET_LEFT)
|
|
{
|
|
nSideFlag = nSideFlag0;
|
|
}
|
|
}
|
|
|
|
return nSideFlag;
|
|
}
|
|
|
|
// 0--Left, 1--Right, 2--Other
|
|
int TGGeCurveSegment::OnWhichSide(const TADSGePoint3d &src) const
|
|
{
|
|
int nSideFlag = 2;
|
|
|
|
TADSGePoint3d ptOnMe;
|
|
if (ProjectToMe(src, ptOnMe) != RTNORM)
|
|
{
|
|
nSideFlag = 2;
|
|
}
|
|
else
|
|
{
|
|
TADSGePoint3d src1 = src;
|
|
src1.z = m_startPoint.z;
|
|
if (src1 == ptOnMe)
|
|
{
|
|
nSideFlag = 2;
|
|
}
|
|
else
|
|
{
|
|
double nDir1 = Direction(ptOnMe);
|
|
double nDir2 = AngleRangeTo2PI(ads_angle(src1, ptOnMe) + PI / 2.0);
|
|
|
|
if (IsExactSameDrt(nDir1, nDir2, _angSnap))
|
|
{
|
|
nSideFlag = OFFSET_LEFT;
|
|
}
|
|
else
|
|
{
|
|
nSideFlag = OFFSET_RIGHT;
|
|
}
|
|
}
|
|
}
|
|
|
|
return nSideFlag;
|
|
}
|
|
|
|
//Wcs到展开坐标系
|
|
TADSGePoint3d TGGeCurveSegment::Wcs2Ecs(TADSGePoint3d pt) const
|
|
{
|
|
TADSGePoint3d ptPrj;
|
|
ProjectToMe(pt, ptPrj);
|
|
|
|
TADSGePoint3d ptExpand;
|
|
ptExpand.x = PathDistance(ptPrj);
|
|
ptExpand.y = (pt.z - m_startPoint.z);
|
|
|
|
double nDist = pt.Distance2d(ptPrj);
|
|
int nSide = OnWhichSide(pt);
|
|
if (nSide == OFFSET_LEFT)
|
|
{
|
|
nDist = -nDist;
|
|
}
|
|
ptExpand.z = nDist;
|
|
|
|
return ptExpand;
|
|
}
|
|
|
|
//展开坐标系到Wcs
|
|
TADSGePoint3d TGGeCurveSegment::Ecs2Wcs(TADSGePoint3d pt) const
|
|
{
|
|
TADSGePointDir2d ptDir;
|
|
Polar(pt.x, ptDir);
|
|
|
|
TADSGePoint3d ptWcs;
|
|
ptWcs = ptDir;
|
|
ptWcs.z = pt.y - m_startPoint.z;
|
|
|
|
if (fabs(pt.z) > _DIST_SNAP)
|
|
{
|
|
ads_polar(TADSGePoint3d(ptWcs), ptDir.nDirection - PI / 2.0, pt.z, ptWcs);
|
|
}
|
|
return ptWcs;
|
|
}
|
|
|
|
void TGGeCurveSegment::Wcs2Ecs(const TGGePoly2D &polyWcs, TGGePoly2D &polyEcs) const
|
|
{
|
|
polyEcs.Reset();
|
|
polyEcs.SetFlag(polyWcs.GetFlag());
|
|
for (int i = 0; i < polyWcs.Length(); i++)
|
|
{
|
|
TADSGePoint3d ptEcs = Wcs2Ecs(polyWcs.GetPointListAt(i));
|
|
polyEcs.AppendNode(ptEcs, polyWcs.GetBulge(i));
|
|
}
|
|
}
|
|
|
|
void TGGeCurveSegment::Ecs2Wcs(const TGGePoly2D &polyEcs, TGGePoly2D &polyWcs) const
|
|
{
|
|
polyWcs.Reset();
|
|
polyWcs.SetFlag(polyEcs.GetFlag());
|
|
for (int i = 0; i < polyEcs.Length(); i++)
|
|
{
|
|
TADSGePoint3d ptWcs = Ecs2Wcs(polyEcs.GetPointListAt(i));
|
|
polyWcs.AppendNode(ptWcs, polyEcs.GetBulge(i));
|
|
}
|
|
|
|
}
|
|
|
|
double TGGeCurveSegment::GetBulge() const
|
|
{
|
|
return m_dBulge;
|
|
}
|
|
|
|
void TGGeCurveSegment::SetBulge(const double dBulge)
|
|
{
|
|
m_dBulge = dBulge;
|
|
}
|
|
|
|
bool TGGeCurveSegment::IsKindOf(TGGeEntity::TEntityId entType) const
|
|
{
|
|
switch(entType)
|
|
{
|
|
case TGGeEntity::eEntity:
|
|
case TGGeEntity::eCurve:
|
|
case TGGeEntity::eLinearEnt:
|
|
case TGGeEntity::eLine:
|
|
case TGGeEntity::eCurveSegment:
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
TGGeEntity::TEntityId TGGeCurveSegment::Type() const
|
|
{
|
|
return TGGeEntity::eCurveSegment;
|
|
}
|
|
|
|
void TGGeCurveSegment::CopyFrom(const TGGeEntity* pSrc)
|
|
{
|
|
if (this != pSrc && pSrc->IsKindOf(TGGeEntity::eCurveSegment))
|
|
{
|
|
TGGeCurveSegment* pEntSeg = (TGGeCurveSegment* )pSrc;
|
|
m_startPoint = pEntSeg->m_startPoint;
|
|
m_endPoint = pEntSeg->m_endPoint;
|
|
m_dBulge = pEntSeg->m_dBulge;
|
|
m_nFlag = pEntSeg->m_nFlag;
|
|
|
|
}
|
|
else if(this != pSrc && pSrc->IsKindOf(TGGeEntity::eLine))
|
|
{
|
|
TGGeCurveSegment* pEntLine = (TGGeCurveSegment* )pSrc;
|
|
m_startPoint = pEntLine->m_startPoint;
|
|
m_endPoint = pEntLine->m_endPoint;
|
|
m_dBulge = 0.0;
|
|
m_nFlag = pEntLine->m_nFlag;
|
|
}
|
|
}
|
|
|
|
|
|
static BOOL IsMirrorTransform(const resbuf *rb1, const resbuf *rb2)
|
|
{
|
|
TADSGePoint3d ptOrg, ptX(1000, 0), ptY(0, 1000), ptOrg1, ptX1, ptY1;
|
|
|
|
ads_trans(ptOrg, rb1, rb2, FALSE, ptOrg1);
|
|
ads_trans(ptX, rb1, rb2, FALSE, ptX1);
|
|
ads_trans(ptY, rb1, rb2, FALSE, ptY1);
|
|
|
|
double nAng = AngleRangeTo2PI(ads_angle(ptOrg1, ptY1) - ads_angle(ptOrg1, ptX1));
|
|
|
|
return (fabs(nAng - PI * 1.5) < _angSnap);
|
|
}
|
|
|
|
TGGeDirectionCurve::TGGeDirectionCurve(const TADSGePoint3d &spt, const TADSGePoint3d &ept, ads_real dAng, int flg)
|
|
: TGGeCurveSegment(spt,ept,dAng, flg)
|
|
{
|
|
|
|
}
|
|
|
|
TGGeDirectionCurve::TGGeDirectionCurve(int flg)
|
|
: TGGeCurveSegment(flg)
|
|
{
|
|
|
|
}
|
|
|
|
TGGeDirectionCurve::TGGeDirectionCurve(const TGGeDirectionCurve &src)
|
|
: TGGeCurveSegment(src)
|
|
{
|
|
|
|
}
|
|
|
|
TGGeDirectionCurve::TGGeDirectionCurve(const TGGeArc &ar, int bMinus)
|
|
{
|
|
TGGeCurveSegment &seg = *this;
|
|
seg = ar;
|
|
|
|
if (bMinus)
|
|
{
|
|
m_dBulge = -fabs(m_dBulge);
|
|
TchPrivate::Exchange(m_startPoint, m_endPoint);
|
|
}
|
|
}
|
|
|
|
TGGeDirectionCurve::~TGGeDirectionCurve()
|
|
{
|
|
|
|
}
|
|
|
|
TGGeArc TGGeDirectionCurve::GetArc() const
|
|
{
|
|
if (IsMinusArc())
|
|
{
|
|
return TGGeArc(m_endPoint, m_startPoint, fabs(m_dBulge));
|
|
}
|
|
|
|
return TGGeArc(m_startPoint, m_endPoint, m_dBulge);
|
|
}
|
|
|
|
int TGGeDirectionCurve::IsMinusArc() const
|
|
{
|
|
return m_dBulge < -1.0E-8;
|
|
}
|
|
|
|
TGGeCurveSegment TGGeDirectionCurve::GetCurve() const
|
|
{
|
|
TGGeCurveSegment seg;
|
|
if (IsMinusArc())
|
|
{
|
|
seg = GetArc();
|
|
}
|
|
else
|
|
{
|
|
seg = *this;
|
|
}
|
|
|
|
return seg;
|
|
}
|
|
|
|
void TGGeDirectionCurve::TransUCS(const resbuf *rb1, const resbuf *rb2)
|
|
{
|
|
TGGeLine::TransUCS(rb2, rb2);
|
|
if (IsMirrorTransform(rb1, rb2))
|
|
{
|
|
m_dBulge = -m_dBulge;
|
|
}
|
|
}
|
|
|
|
void TGGeDirectionCurve::TransUCS(ads_matrix mat)
|
|
{
|
|
TGGeLine::TransformBy(mat);
|
|
if (IsMirrorMatrix(mat))
|
|
{
|
|
m_dBulge = -m_dBulge;
|
|
}
|
|
}
|
|
|
|
void TGGeDirectionCurve::Reverse()
|
|
{
|
|
TchPrivate::Exchange(m_startPoint, m_endPoint);
|
|
m_dBulge = -m_dBulge;
|
|
}
|
|
|
|
// dist: <0 left side; >0 right siede
|
|
TGGeDirectionCurve TGGeDirectionCurve::Offset(ads_real dist, int flg) const
|
|
{
|
|
assert(!Is(CURVE_CIRCLE));
|
|
|
|
TADSGePoint3d spt, ept;
|
|
if (Is(CURVE_LINE))
|
|
{
|
|
ads_real ang = TGGeLine::Direction()-PI/2.0;
|
|
ads_polar(m_startPoint, ang, dist, spt);
|
|
ads_polar(m_endPoint, ang, dist, ept);
|
|
|
|
return TGGeDirectionCurve(spt, ept, 0.0, flg);
|
|
}
|
|
|
|
TGGeArc aArc = GetArc();
|
|
ads_real r = (!IsMinusArc()) ? (aArc.GetRadius() + dist) : (aArc.GetRadius() - dist);
|
|
|
|
if (r < _DIST_SNAP)
|
|
{
|
|
return TGGeDirectionCurve();
|
|
}
|
|
|
|
aArc.SetRadius(r);
|
|
|
|
TGGeDirectionCurve curve(aArc, IsMinusArc());
|
|
curve.m_nFlag = flg;
|
|
return curve;
|
|
}
|
|
|
|
ads_real TGGeDirectionCurve::IDirection(int npt) const
|
|
{
|
|
if (IsMinusArc())
|
|
{
|
|
return GetCurve().IDirection(1 - npt);
|
|
}
|
|
|
|
return TGGeCurveSegment::IDirection(npt);
|
|
}
|
|
|
|
int TGGeDirectionCurve::OnWhichSide(const TADSGePoint3d &src) const
|
|
{
|
|
int nSide = GetCurve().OnWhichSide(src);
|
|
if (IsMinusArc())
|
|
{
|
|
nSide = 1 - nSide;
|
|
}
|
|
|
|
return nSide;
|
|
}
|
|
|
|
int TGGeDirectionCurve::OnWhichSide1(const TADSGePoint3d &src) const
|
|
{
|
|
int nSide = GetCurve().OnWhichSide1(src);
|
|
if (IsMinusArc())
|
|
{
|
|
nSide = 1 - nSide;
|
|
}
|
|
|
|
return nSide;
|
|
}
|
|
|
|
ads_real TGGeDirectionCurve::PathArea(TADSGePoint3d &tmpt) const
|
|
{
|
|
double nRet = GetCurve().PathArea(tmpt);
|
|
if (IsMinusArc())
|
|
{
|
|
nRet = -nRet;
|
|
}
|
|
|
|
return nRet;
|
|
}
|
|
|
|
ads_real TGGeDirectionCurve::Direction(const TADSGePoint3d &pt) const
|
|
{
|
|
double nRet = GetCurve().Direction(pt);
|
|
if (IsMinusArc())
|
|
{
|
|
nRet = -nRet;
|
|
}
|
|
|
|
return nRet;
|
|
}
|
|
|
|
void TGGeDirectionCurve::AsPoly2D(TGGePoly2D &poly) const
|
|
{
|
|
GetCurve().AsPoly2D(poly);
|
|
if (IsMinusArc())
|
|
{
|
|
poly.Reverse();
|
|
}
|
|
}
|
|
|
|
// 从端点开始沿曲线走过给定距离的点向量
|
|
int TGGeDirectionCurve::Polar(ads_real dDist, TADSGePointDir2d &res, BOOL bFromStart) const
|
|
{
|
|
return GetCurve().Polar(dDist, res, IsMinusArc() ? (!bFromStart) : bFromStart);
|
|
}
|
|
|
|
// 求到端点的沿曲线线位移, 在线内距离为正,否则为负, 和Polar配合使用
|
|
// pt如果不在线上的话则先投影
|
|
ads_real TGGeDirectionCurve::PathDistance(const TADSGePoint3d &pt, BOOL bFromStart) const
|
|
{
|
|
return GetCurve().PathDistance(pt, IsMinusArc() ? (!bFromStart) : bFromStart);
|
|
}
|
|
|
|
// 求通过pt点的法向
|
|
ads_real TGGeDirectionCurve::OrthoDirection(const TADSGePoint3d &pt) const
|
|
{
|
|
double nRet = GetCurve().OrthoDirection(pt);
|
|
if (IsMinusArc())
|
|
{
|
|
nRet = AngleRangeTo2PI(nRet + PI);
|
|
}
|
|
|
|
return nRet;
|
|
}
|
|
|
|
void TGGeDirectionCurve::SetPoints(const TADSGePoint3d &ptStart, const TADSGePoint3d &ptEnd)
|
|
{
|
|
if (IsMinusArc())
|
|
{
|
|
TGGeCurveSegment seg = GetCurve();
|
|
seg.SetPoints(ptEnd, ptStart);
|
|
m_startPoint = seg.GetEndPoint();
|
|
m_endPoint = seg.GetStartPoint();
|
|
m_dBulge = -seg.GetBulge();
|
|
}
|
|
else
|
|
{
|
|
TGGeCurveSegment::SetPoints(ptStart, ptEnd);
|
|
}
|
|
}
|
|
|
|
bool TGGeDirectionCurve::IsDirectionCurve()
|
|
{
|
|
return true;
|
|
}
|
|
|