#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(""), 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; }