Files
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

1422 lines
29 KiB
C++

#include "StdAfx.h"
#include "GeCurveSegment.h"
#include "ADSGePointDir2d.h"
#include "AcDbObjectPtr.h"
#include "GeCurveInline.h"
#include "GlobalFunc.h"
GeCurveSegment::GeCurveSegment(int flg)
: GeLine(flg),m_dBulge(0.0)
{
}
GeCurveSegment::GeCurveSegment(const EntitySet &e, int flg)
: GeLine(flg),m_dBulge(0.0)
{
AcDbObjectPtr 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;
ADSGePoint3d ptCen;
(AcGePoint3d &)ptCen = pLine->center();
TVector3D vtNormal;
(AcGeVector3d &)vtNormal = pLine->normal();
ptCen = GlobalFunc::Wcs2Ecs(ptCen, vtNormal);
GeArc 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;
ADSGePoint3d ptCen;
(AcGePoint3d &)ptCen = pLine->center();
TVector3D vtNormal;
(AcGeVector3d &)vtNormal = pLine->normal();
ptCen = GlobalFunc::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;
}
}
GeCurveSegment::GeCurveSegment(const ADSGePoint3d &spt, const ADSGePoint3d &ept, ads_real ang, int flg)
: GeLine(spt,ept,flg)
{
m_dBulge = ang;
}
GeCurveSegment::GeCurveSegment(const GeCurveSegment &src)
: GeLine(LS_FINITE)
{
m_startPoint = src.m_startPoint;
m_endPoint = src.m_endPoint;
m_dBulge = src.m_dBulge;
m_nFlag = src.m_nFlag;
}
GeCurveSegment::~GeCurveSegment()
{
}
//lfy 2010-08-31 增加line,arc的set函数
GeCurveSegment & GeCurveSegment::SetLine(const ADSGePoint3d& pt1, const ADSGePoint3d& pt2)
{
m_nFlag = LS_INFINITE;
m_startPoint = pt1;
m_endPoint = pt2;
m_dBulge = 0.0;
return *this;
}
GeCurveSegment & GeCurveSegment:: SetArc(const ADSGePoint3d &spt, const ADSGePoint3d &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;
ADSGePoint3d 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;
}
GeCurveSegment & GeCurveSegment::SetCircle(const ADSGePoint3d& 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 * GeCurveSegment::AsAcDbCurve() const
{
AcDbCurve *pCurve = NULL;
if (Is(CURVE_LINE))
{
pCurve = new AcDbLine(m_startPoint, m_endPoint);
}
else if (Is(CURVE_ARC))
{
GeArc ar = GetArc();
pCurve = new AcDbArc(ar.GetCenterPt(), ar.GetRadius(), ar.GetStarAngle(), ar.GetEndAngle());
}
return pCurve;
}
resbuf *GeCurveSegment::Mask(LPCTSTR pszLay)
{
CString 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 GeCurveSegment::MakeArrow(EntitySet &res) const
{
ads_point cpt, pt1, pt2, pt3;
ads_real arrowWidth = 200,
arrowWidthFactor = 5.0;
ADSGePoint3d 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 GeCurveSegment::PathArea(ADSGePoint3d &spt) const
{
spt.z = GetStartPoint().z;
ADSGePoint3d 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 GeCurveSegment::GetDist2Me(ADSGePoint3d ptMid) const
{
ADSGePoint3d 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 GeCurveSegment::GetSubSegment(const ADSGePoint3d &ptloc, ads_real dchordLen, GeCurveSegment &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))
{
GeArc arc1 = GetArc(), arc;
if (m_nFlag == LS_INFINITE)
{
rc = GeCircle(arc1.m_ptCenter, arc1.m_dRadius).GetSubArc(ptloc, dchordLen, arc);
}
else
{
rc = arc1.GetSubArc(ptloc, dchordLen, arc);
}
if (rc == RTNORM)
{
ADSGePoint3d ptStart = res.StartPoint();
ADSGePoint3d 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))
{
GeArc arc;
rc = GetCircle().GetSubArc(ptloc, dchordLen, arc);
if (rc == RTNORM)
{
ADSGePoint3d 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;
}
ADSGePoint3d GeCurveSegment::MidPoint() const
{
ADSGePoint3d mpt;
if (Is(CURVE_LINE))
{
mpt = GeLine::MidPoint();
}
else if (Is(CURVE_ARC))
{
GetArc().MidPoint(mpt);
}
else
{
return GetStartPoint();
}
return mpt;
}
ads_real GeCurveSegment::GetLength() const
{
if (Is(CURVE_LINE))
{
return GeLine::GetLength();
}
else if (Is(CURVE_ARC))
{
return GetArc().GetLength();
}
else
{
return GetCircle().GetLength();
}
}
void GeCurveSegment::SetPoints(const ADSGePoint3d &ptStart, const ADSGePoint3d &ptEnd)
{
assert(!Is(CURVE_CIRCLE));
if (Is(CURVE_ARC))
{
GeArc ar = GetArc();
ar.SetAngleByPoints(ptStart, ptEnd);
*this = ar;
}
else
{
//GeLine::SetPoints(ptStart, ptEnd);
m_startPoint = ptStart;
m_endPoint = ptEnd;
}
}
GeCircle GeCurveSegment::GetCircle() const
{
return GeCircle(m_startPoint, m_endPoint);
}
GeArc GeCurveSegment::GetArc() const
{
return GeArc(m_startPoint, m_endPoint, m_dBulge);
}
int GeCurveSegment::Intersection(const GeCurveSegment& 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))
{
GeArc aArc = curve.GetArc();
if (curve.GetLineFlag() == LS_INFINITE)
{
GeCircle aCir = aArc;
int rc = Intersection(&aCir, pt1, pt2);
return rc;
}
else
{
return Intersection(&aArc, pt1, pt2);
}
}
else
{
GeCircle cir(curve.GetCircle());
return Intersection(&cir, pt1, pt2);
}
}
int GeCurveSegment::Intersection(const GeLine& line, ads_point pt1, ads_point pt2) const
{
if(Is(CURVE_LINE))
{
return GetLine().Intersection(&line, pt1);
}
else if(Is(CURVE_ARC))
{
GeArc aArc = GetArc();
if(m_nFlag == LS_FINITE)
{
return aArc.Intersection(&line, pt1, pt2);
}
GeCircle aCir = aArc;
int rc = aCir.Intersection(&line, pt1, pt2);
return rc;
}
else
{
return GetCircle().Intersection(&line, pt1, pt2);
}
}
int GeCurveSegment::Intersection(const GeArc* pArc, ads_point pt1, ads_point pt2) const
{
if (Is(CURVE_LINE))
{
return GetLine().Intersection(pArc, pt1,pt2);
}
else if (Is(CURVE_ARC))
{
GeArc aArc = GetArc();
if (m_nFlag == LS_FINITE)
{
return aArc.Intersection(pArc, pt1, pt2);
}
GeCircle aCir = aArc;
int rc = aCir.Intersection(pArc, pt1, pt2);
return rc;
}
else
{
return GetCircle().Intersection(pArc, pt1, pt2);
}
}
int GeCurveSegment::Intersection(const GeCircle* pCir, ads_point pt1, ads_point pt2) const
{
if (Is(CURVE_LINE))
{
return GetLine().Intersection(pCir, pt1,pt2);
}
else if (Is(CURVE_ARC))
{
GeArc aArc = GetArc();
if (m_nFlag == LS_FINITE)
{
return aArc.Intersection(pCir, pt1, pt2);
}
GeCircle aCir = aArc;
int rc = aCir.Intersection(pCir, pt1, pt2);
return rc;
}
else
{
return GetCircle().Intersection(pCir, pt1, pt2);
}
}
int GeCurveSegment::ProjectToMe(const ADSGePoint3d &src, ADSGePoint3d &res) const
{
//lfy 2010-08-31 下面两句似乎无用
/*ADSGePoint3d src1 = src;
src1.z = GetStartPoint().z;*/
if (Is(CURVE_LINE))
{
return GlobalFunc::PointProjectToLine(src, m_startPoint, m_endPoint, res);
}
else if (Is(CURVE_ARC))
{
GeArc arc(GetArc());
return src.Project(&arc, res);
}
else
{
GeCircle cir(GetCircle());
return src.Project(&cir, res);
}
return -1;
}
int GeCurveSegment::Make(const TCHAR *pszLay) const
{
if (Is(CURVE_LINE))
{
GeLine::Make(pszLay);
}
else if (Is(CURVE_ARC))
{
GetArc().Make(pszLay);
}
else
{
GetCircle().Make(pszLay);
}
return RTNORM;
}
int GeCurveSegment::OSnap(int nMode, ADSGePoint3d &ptPick) const
{
if (Is(CURVE_LINE))
{
return GeLine::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 GeCurveSegment::AsPoly2D(GePoly2D &poly) const
{
//用两个弧来近似
if (Is(CURVE_CIRCLE))
{
poly.AppendPointListAt(new ADSGePoint3d(m_startPoint));
poly.AppendBugle(PI);
poly.AppendPointListAt(new ADSGePoint3d(m_endPoint));
poly.AppendBugle(PI);
poly.SetFlag(1);
}
else
{
poly.AppendPointListAt(new ADSGePoint3d(m_startPoint));
poly.AppendBugle(m_dBulge);
poly.AppendPointListAt(new ADSGePoint3d(m_endPoint));
poly.AppendBugle(0.0);
poly.SetFlag(0);
}
}
// 把曲线化作篱笆
resbuf * GeCurveSegment::AsFence(int nCirDiv) const
{
GePoly2D poly(0);
AsPoly2D(poly);
return poly.Fence();
}
ads_real GeCurveSegment::IDirection(int npt) const
{
using namespace GlobalFunc;
ads_real result;
if (Is(CURVE_LINE))
{
result = npt ? RevDrtAngle(GeLine::Direction()) : GeLine::Direction();
}
else if (Is(CURVE_ARC))
{
GeArc aArc(m_startPoint, m_endPoint, m_dBulge);
result = aArc.IDirection(npt);
}
else
{
g_Option::instance().adsout << _T("\nInvalid Call to IDirection() for Circle!");
}
return result;
}
ads_real GeCurveSegment::Direction(const ADSGePoint3d &pt) const
{
//lfy 2010-08-31 修改值传递
ADSGePoint3d cpt;
if (Is(CURVE_LINE))
{
return GeLine::Direction();
}
else if (Is(CURVE_ARC))
{
cpt = GetArc().m_ptCenter;
}
else
{
cpt = GetCircle().m_ptCenter;
}
return GlobalFunc::AngleRangeTo2PI(ads_angle(cpt, pt) + PI / 2.0);
}
// 求通过pt点的法向
ads_real GeCurveSegment::OrthoDirection(const ADSGePoint3d &pt) const
{
return GlobalFunc::AngleRangeTo2PI(GeCurveSegment::Direction(pt) - PI / 2.0);
}
// Following should move to GeCurveSegment
// 从端点开始沿曲线走过给定距离的点向量
int GeCurveSegment::Polar(ads_real dDist, ADSGePointDir2d &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 ? GeLine::Direction() : GlobalFunc::AngleRangeTo2PI(GeLine::Direction() + PI);
ads_polar(bFromStart ? m_startPoint : m_endPoint, nDrt, dDist, ptres);
ptres.nDirection = dDist > -1.0E-9 ? nDrt : GlobalFunc::AngleRangeTo2PI(nDrt + PI);
}
else
{
GeArc arc = GetArc();
ads_real nAcrossAngle = dDist / arc.m_dRadius;
if (!bFromStart)
{
nAcrossAngle = -nAcrossAngle;
}
ads_real nPositionAngle = GlobalFunc::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 = GlobalFunc::AngleRangeTo2PI(nPositionAngle + PI / 2.0 + nFactor * PI);
}
return RTNORM;
}
// 求到端点的沿曲线线位移, 在线内距离为正,否则为负, 和Polar配合使用
// pt如果不在线上的话则先投影
// Note: 不能用于CIRCLE
ads_real GeCurveSegment::PathDistance(const ADSGePoint3d &pt, int bFromStart) const
{
assert(!Is(CURVE_CIRCLE));
ADSGePoint3d ptOnBase;
ProjectToMe(pt, ptOnBase);
const GeCurveSegment &thisCurve = *this;
int nPrFlag = ptOnBase & thisCurve;
const ADSGePoint3d &ptEnd = bFromStart ? m_startPoint : m_endPoint;
const ADSGePoint3d &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
{
GeArc 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
{
GeArc ar = GetArc();
//GeArc 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 GeCurveSegment::IsDirectionCurve()
{
return false;
}
GeCurveSegment GeCurveSegment::Offset(double dDist, int nflg) const
{
return Offset(OFFSET_RIGHT, dDist, nflg);
}
// lr-- 0:逆时针,左侧; 1:顺时针,右侧
GeCurveSegment GeCurveSegment::Offset(int nlr, ads_real dDist, int nflg) const
{
//lfy 2008-08-31 修改值传递
ads_real ang = nlr ? -PI / 2.0 : PI / 2.0; //右:顺时针;左:逆时针
ADSGePoint3d spt, ept;
if (Is(CURVE_LINE))
{
ang = GlobalFunc::AngleRangeTo2PI(GeLine::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;
}
GeArc aArc(m_startPoint, m_endPoint, ang);
ads_real r = nlr ? (aArc.m_dRadius + dDist) : (aArc.m_dRadius - dDist);
if (r < g_Option::instance()._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 GeCurveSegment(spt, ept, m_dBulge, nflg);
}
void GeCurveSegment::TransformBy(ads_matrix mat)
{
if (Is(CURVE_LINE))
{
m_startPoint.TransformBy(mat);
m_endPoint.TransformBy(mat);
}
else if (Is(CURVE_ARC))
{
ADSGePoint3d ptMid = MidPoint();
m_startPoint.TransformBy(mat);
m_endPoint.TransformBy(mat);
ptMid.TransformBy(mat);
(GeCurveSegment &)(*this) = GeArc(m_startPoint, ptMid, m_endPoint);
}
}
int GeCurveSegment::OnWhichSide1(const ADSGePoint3d &src) const
{
using namespace GlobalFunc;
int nSideFlag = 2;
ADSGePoint3d ptOnMe;
if (ProjectToMe(src, ptOnMe) != RTNORM)
{
nSideFlag = 2;
}
else
{
ADSGePoint3d src1 = src;
src1.z = m_startPoint.z;
if (src1 == ptOnMe)
{
nSideFlag = 2;
}
else
{
double nDir1 = Direction(ptOnMe);
double nDir2 = GlobalFunc::AngleRangeTo2PI(ads_angle(src1, ptOnMe) + PI / 2.0);
if (IsExactSameDrt(nDir1, nDir2, g_DimOption::instance()._angSnap))
{
nSideFlag = OFFSET_LEFT;
}
else
{
nSideFlag = OFFSET_RIGHT;
}
}
}
if (Is(CURVE_ARC))
{
int nSideFlag0 = GeLine::OnWhichSide(src);
if (nSideFlag0 == OFFSET_LEFT)
{
nSideFlag = nSideFlag0;
}
}
return nSideFlag;
}
// 0--Left, 1--Right, 2--Other
int GeCurveSegment::OnWhichSide(const ADSGePoint3d &src) const
{
using namespace GlobalFunc;
int nSideFlag = 2;
ADSGePoint3d ptOnMe;
if (ProjectToMe(src, ptOnMe) != RTNORM)
{
nSideFlag = 2;
}
else
{
ADSGePoint3d src1 = src;
src1.z = m_startPoint.z;
if (src1 == ptOnMe)
{
nSideFlag = 2;
}
else
{
double nDir1 = Direction(ptOnMe);
double nDir2 = GlobalFunc::AngleRangeTo2PI(ads_angle(src1, ptOnMe) + PI / 2.0);
if (IsExactSameDrt(nDir1, nDir2, g_DimOption::instance()._angSnap))
{
nSideFlag = OFFSET_LEFT;
}
else
{
nSideFlag = OFFSET_RIGHT;
}
}
}
return nSideFlag;
}
//Wcs到展开坐标系
ADSGePoint3d GeCurveSegment::Wcs2Ecs(ADSGePoint3d pt) const
{
ADSGePoint3d ptPrj;
ProjectToMe(pt, ptPrj);
ADSGePoint3d 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
ADSGePoint3d GeCurveSegment::Ecs2Wcs(ADSGePoint3d pt) const
{
ADSGePointDir2d ptDir;
Polar(pt.x, ptDir);
ADSGePoint3d ptWcs;
ptWcs = ptDir;
ptWcs.z = pt.y - m_startPoint.z;
if (fabs(pt.z) > g_Option::instance()._DIST_SNAP)
{
ads_polar(ADSGePoint3d(ptWcs), ptDir.nDirection - PI / 2.0, pt.z, ptWcs);
}
return ptWcs;
}
void GeCurveSegment::Wcs2Ecs(const GePoly2D &polyWcs, GePoly2D &polyEcs) const
{
polyEcs.Reset();
polyEcs.SetFlag(polyWcs.GetFlag());
for (int i = 0; i < polyWcs.Length(); i++)
{
ADSGePoint3d ptEcs = Wcs2Ecs(polyWcs.GetPointListAt(i));
polyEcs.AppendNode(ptEcs, polyWcs.GetBulge(i));
}
}
void GeCurveSegment::Ecs2Wcs(const GePoly2D &polyEcs, GePoly2D &polyWcs) const
{
polyWcs.Reset();
polyWcs.SetFlag(polyEcs.GetFlag());
for (int i = 0; i < polyEcs.Length(); i++)
{
ADSGePoint3d ptWcs = Ecs2Wcs(polyEcs.GetPointListAt(i));
polyWcs.AppendNode(ptWcs, polyEcs.GetBulge(i));
}
}
double GeCurveSegment::GetBulge() const
{
return m_dBulge;
}
void GeCurveSegment::SetBulge(const double dBulge)
{
m_dBulge = dBulge;
}
bool GeCurveSegment::IsKindOf(GeEntity::TEntityId entType) const
{
switch(entType)
{
case GeEntity::eEntity:
case GeEntity::eCurve:
case GeEntity::eLinearEnt:
case GeEntity::eLine:
case GeEntity::eCurveSegment:
return true;
}
return false;
}
GeEntity::TEntityId GeCurveSegment::Type() const
{
return GeEntity::eCurveSegment;
}
void GeCurveSegment::CopyFrom(const GeEntity* pSrc)
{
if (this != pSrc && pSrc->IsKindOf(GeEntity::eCurveSegment))
{
GeCurveSegment* pEntSeg = (GeCurveSegment* )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(GeEntity::eLine))
{
GeCurveSegment* pEntLine = (GeCurveSegment* )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)
{
ADSGePoint3d 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 = GlobalFunc::AngleRangeTo2PI(ads_angle(ptOrg1, ptY1) - ads_angle(ptOrg1, ptX1));
return (fabs(nAng - PI * 1.5) < g_DimOption::instance()._angSnap);
}
GeDirectionCurve::GeDirectionCurve(const ADSGePoint3d &spt, const ADSGePoint3d &ept, ads_real dAng, int flg)
: GeCurveSegment(spt,ept,dAng, flg)
{
}
GeDirectionCurve::GeDirectionCurve(int flg)
: GeCurveSegment(flg)
{
}
GeDirectionCurve::GeDirectionCurve(const GeDirectionCurve &src)
: GeCurveSegment(src)
{
}
GeDirectionCurve::GeDirectionCurve(const GeArc &ar, int bMinus)
{
GeCurveSegment &seg = *this;
seg = ar;
if (bMinus)
{
m_dBulge = -fabs(m_dBulge);
GlobalFunc::Exchange(m_startPoint, m_endPoint);
}
}
GeDirectionCurve::~GeDirectionCurve()
{
}
GeArc GeDirectionCurve::GetArc() const
{
if (IsMinusArc())
{
return GeArc(m_endPoint, m_startPoint, fabs(m_dBulge));
}
return GeArc(m_startPoint, m_endPoint, m_dBulge);
}
int GeDirectionCurve::IsMinusArc() const
{
return m_dBulge < -1.0E-8;
}
GeCurveSegment GeDirectionCurve::GetCurve() const
{
GeCurveSegment seg;
if (IsMinusArc())
{
seg = GetArc();
}
else
{
seg = *this;
}
return seg;
}
void GeDirectionCurve::TransUCS(const resbuf *rb1, const resbuf *rb2)
{
GeLine::TransUCS(rb2, rb2);
if (IsMirrorTransform(rb1, rb2))
{
m_dBulge = -m_dBulge;
}
}
void GeDirectionCurve::TransUCS(ads_matrix mat)
{
GeLine::TransformBy(mat);
if (GlobalFunc::IsMirrorMatrix(mat))
{
m_dBulge = -m_dBulge;
}
}
void GeDirectionCurve::Reverse()
{
GlobalFunc::Exchange(m_startPoint, m_endPoint);
m_dBulge = -m_dBulge;
}
// dist: <0 left side; >0 right siede
GeDirectionCurve GeDirectionCurve::Offset(ads_real dist, int flg) const
{
assert(!Is(CURVE_CIRCLE));
ADSGePoint3d spt, ept;
if (Is(CURVE_LINE))
{
ads_real ang = GeLine::Direction()-PI/2.0;
ads_polar(m_startPoint, ang, dist, spt);
ads_polar(m_endPoint, ang, dist, ept);
return GeDirectionCurve(spt, ept, 0.0, flg);
}
GeArc aArc = GetArc();
ads_real r = (!IsMinusArc()) ? (aArc.GetRadius() + dist) : (aArc.GetRadius() - dist);
if (r < g_Option::instance()._DIST_SNAP)
{
return GeDirectionCurve();
}
aArc.SetRadius(r);
GeDirectionCurve curve(aArc, IsMinusArc());
curve.m_nFlag = flg;
return curve;
}
ads_real GeDirectionCurve::IDirection(int npt) const
{
if (IsMinusArc())
{
return GetCurve().IDirection(1 - npt);
}
return GeCurveSegment::IDirection(npt);
}
int GeDirectionCurve::OnWhichSide(const ADSGePoint3d &src) const
{
int nSide = GetCurve().OnWhichSide(src);
if (IsMinusArc())
{
nSide = 1 - nSide;
}
return nSide;
}
int GeDirectionCurve::OnWhichSide1(const ADSGePoint3d &src) const
{
int nSide = GetCurve().OnWhichSide1(src);
if (IsMinusArc())
{
nSide = 1 - nSide;
}
return nSide;
}
ads_real GeDirectionCurve::PathArea(ADSGePoint3d &tmpt) const
{
double nRet = GetCurve().PathArea(tmpt);
if (IsMinusArc())
{
nRet = -nRet;
}
return nRet;
}
ads_real GeDirectionCurve::Direction(const ADSGePoint3d &pt) const
{
double nRet = GetCurve().Direction(pt);
if (IsMinusArc())
{
nRet = -nRet;
}
return nRet;
}
void GeDirectionCurve::AsPoly2D(GePoly2D &poly) const
{
GetCurve().AsPoly2D(poly);
if (IsMinusArc())
{
poly.Reverse();
}
}
// 从端点开始沿曲线走过给定距离的点向量
int GeDirectionCurve::Polar(ads_real dDist, ADSGePointDir2d &res, BOOL bFromStart) const
{
return GetCurve().Polar(dDist, res, IsMinusArc() ? (!bFromStart) : bFromStart);
}
// 求到端点的沿曲线线位移, 在线内距离为正,否则为负, 和Polar配合使用
// pt如果不在线上的话则先投影
ads_real GeDirectionCurve::PathDistance(const ADSGePoint3d &pt, BOOL bFromStart) const
{
return GetCurve().PathDistance(pt, IsMinusArc() ? (!bFromStart) : bFromStart);
}
// 求通过pt点的法向
ads_real GeDirectionCurve::OrthoDirection(const ADSGePoint3d &pt) const
{
double nRet = GetCurve().OrthoDirection(pt);
if (IsMinusArc())
{
nRet = GlobalFunc::AngleRangeTo2PI(nRet + PI);
}
return nRet;
}
void GeDirectionCurve::SetPoints(const ADSGePoint3d &ptStart, const ADSGePoint3d &ptEnd)
{
if (IsMinusArc())
{
GeCurveSegment seg = GetCurve();
seg.SetPoints(ptEnd, ptStart);
m_startPoint = seg.GetEndPoint();
m_endPoint = seg.GetStartPoint();
m_dBulge = -seg.GetBulge();
}
else
{
GeCurveSegment::SetPoints(ptStart, ptEnd);
}
}
bool GeDirectionCurve::IsDirectionCurve()
{
return true;
}
bool GeCurveSegment::operator == (const GeCurveSegment &src) const
{
bool bRet = false;
if (src.GetCurveType() != GetCurveType())
{
bRet = false;
}
else if (Is(CURVE_LINE))
{
bRet = (GetLine() == src.GetLine());
}
else if (Is(CURVE_ARC))
{
bRet = (GetArc() == src.GetArc());
}
else
{
bRet = (GetCircle() == src.GetCircle());
}
return bRet;
}
int GeCurveSegment::Is(CurveType t) const
{
double dBulge = fabs(GetBulge());
return ((dBulge < 1E-6 && t == CURVE_LINE)
|| (fabs(2.0 * PI - dBulge) < 1E-5 && t == CURVE_CIRCLE)
|| (dBulge > 1E-6 && dBulge < 2.0 * PI - 1E-6 && t == CURVE_ARC));
}
CurveType GeCurveSegment::GetCurveType() const
{
CurveType t;
double dBulge = fabs(GetBulge());
if (dBulge < 1E-6)
{
t = CURVE_LINE;
}
else if (fabs(2.0 * PI - dBulge) < 1E-5)
{
t = CURVE_CIRCLE;
}
else
{
t = CURVE_ARC;
}
return t;
}
GeLine GeCurveSegment::GetLine() const
{
return *this;
}
double GeCurveSegment::GetChordLength(double nArcLen) const
{
double nRes = nArcLen;
if (Is(CURVE_ARC))
{
GeArc ar = GetArc();
double dRadius = ar.GetRadius();
nRes = 2.0 * dRadius * sin(nArcLen / 2.0 / dRadius);
}
return fabs(nRes);
}
int GeCurveSegment::HitTest2d(const ADSGePoint3d &ptTest) const
{
CurveType t = GetCurveType();
int nHitFlag = 0;
if (t == CURVE_LINE)
{
nHitFlag = GetLine().HitTest2d(ptTest);
}
else if (t == CURVE_ARC)
{
nHitFlag = GetArc().HitTest2d(ptTest);
}
else if (t == CURVE_CIRCLE)
{
nHitFlag = GetCircle().HitTest2d(ptTest);
}
return nHitFlag;
}
int GeCurveSegment::MakeEntity(const EntitySet &e)
{
if (Is(CURVE_LINE))
{
return GetLine().MakeEntity(&e);
}
if (Is(CURVE_ARC))
{
return GetArc().MakeEntity(&e);
}
if (Is(CURVE_CIRCLE))
{
return GetCircle().MakeEntity(&e);
}
return RTERROR;
}
int GeCurveSegment::GetExtend(ADSGePoint3d &lowPt, ADSGePoint3d &upPt) const
{
if (Is(CURVE_LINE))
{
return GeLine::GetExtend(lowPt, upPt);
}
else if (Is(CURVE_ARC))
{
return GetArc().GetExtend(lowPt, upPt);
}
else
{
return GetCircle().GetExtend(lowPt, upPt);
}
}
GeCurveSegment & GeCurveSegment::operator = (const GeCurveSegment &src)
{
if (this != &src)
{
m_nFlag = src.m_nFlag;
m_startPoint = src.m_startPoint;
m_endPoint = src.m_endPoint;
m_dBulge = src.m_dBulge;
}
return *this;
}
GeCurveSegment & GeCurveSegment::operator = (const GeLine &ln)
{
m_nFlag = ln.m_nFlag;
m_startPoint = ln.m_startPoint;
m_endPoint = ln.m_endPoint;
m_dBulge = 0.0;
return *this;
}
GeCurveSegment & GeCurveSegment::operator = (const GeArc &arc)
{
//SetLineFlag(LS_FINITE);
m_nFlag = LS_FINITE;
ADSGePoint3d ptStart, ptEnd;
ADSGePoint3d ptCen = arc.GetCenterPt();
double dRadius = arc.GetRadius();
ads_polar(ptCen, arc.GetStarAngle(), dRadius, ptStart);
ads_polar(ptCen, arc.GetEndAngle(), dRadius, ptEnd);
m_startPoint = ptStart;
m_endPoint = ptEnd;
m_dBulge = arc.Bulge();
return *this;
}
GeCurveSegment & GeCurveSegment::operator = (const GeCircle &cir)
{
ADSGePoint3d ptStart, ptEnd;
ADSGePoint3d ptCen = cir.GetCenterPt();
double dRadius = cir.GetRadius();
ads_polar(ptCen, 0.0, dRadius, ptStart);
ads_polar(ptCen, PI, dRadius, ptEnd);
m_startPoint = ptStart;
m_endPoint = ptEnd;
m_dBulge = 2.0 * PI;
return *this;
}