//-------------------------------------------------------------------------------------------------------+ // Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd. // = FileName : TPGeCircle2D 类 // = Version : ver2.0 // = Author : wlw // = CreateDate : 2002-09-09 // = Description: TPGeCircle2D 定义 // = Maintainers: // //-------------------------------------------------------------------------------------------------------+ #include "StdAfx.h" #include "TPGeCircle2D.h" #include "TGPoint2D.h" #include "TPGeGLine2D.h" #include "TPGeGLineRay2D.h" // #include "TchGeLib.h" double TPGeCircle2D::g_fMLinePreci = 0.1; IMPLEMENT_RUN_TIME_CLASS1(TPGeCircle2D,"TPGeCircle2D",TPGeCurve2D) TPGeCircle2D::TPGeCircle2D(bool bUnclock/* = true*/) { if (!bUnclock) { AddFlag(CLOCKWISE_CURVE); } } TPGeCircle2D::TPGeCircle2D(const TGPoint& pt,double r,bool bUnclock/* = true*/):TPGeCircle(pt,r) { if (!bUnclock) { AddFlag(CLOCKWISE_CURVE); } } TPGeCircle2D::TPGeCircle2D(const TPGeCircle& circle,bool bUnclock/* = true*/):TPGeCircle(circle) { if (!bUnclock) { AddFlag(CLOCKWISE_CURVE); } } TPGeCircle2D::TPGeCircle2D(const TGPoint& pt0,const TGPoint& pt1,const TGPoint& pt2) { Init(pt0,pt1,pt2); } TPGeCircle2D::TPGeCircle2D(const TGPoint& pt0,const TGPoint& pt1,double angle) { Init(pt0,pt1,angle); } TPGeCircle2D::~TPGeCircle2D() { } void TPGeCircle2D::GetTangent(double pa,TPGeLine2D&line) const { if (Is(CLOCKWISE_CURVE)) { TPGeCircle::GetTangent(PI2 - pa,line); line.Reverse(); } else { TPGeCircle::GetTangent(pa,line); } } void TPGeCircle2D::Pt2Pa(const TGPoint& pt,double&pa) const { TPGeCircle::Pt2Pa(pt,pa); if (Is(CLOCKWISE_CURVE)) { pa = PI2 - pa; } } void TPGeCircle2D::Pa2Pt(double pa,TGPoint& pt) const { if (Is(CLOCKWISE_CURVE)) { TPGeCircle::Pa2Pt(PI2-pa,pt); } else { TPGeCircle::Pa2Pt(pa,pt); } } void TPGeCircle2D::SetMLinePreci(double preci) { g_fMLinePreci = preci; } void TPGeCircle2D::Reverse() { if (Is(CLOCKWISE_CURVE)) { RemoveFlag(CLOCKWISE_CURVE); } else { AddFlag(CLOCKWISE_CURVE); } } bool TPGeCircle2D::IsClosed() const { return true; } bool TPGeCircle2D::IsFinite(bool bStart) const { return false; } bool TPGeCircle2D::IsClockwise() const { return Is(CLOCKWISE_CURVE); } double TPGeCircle2D::Area() const { return TPGeCircle::Area(); } double TPGeCircle2D::Length() const { return TPGeCircle::Length(); } double TPGeCircle2D::GetMLinePrec() const { return g_fMLinePreci; } bool TPGeCircle2D::Offset(double offset) { if (IsClockwise()) { offset = -offset; } return TPGeCircle::Offset(offset); } void TPGeCircle2D::SetElev(double elev) { center.z = elev; } double TPGeCircle2D::GetElev() const { return center.z; } bool TPGeCircle2D::IsValid() const { return TPGeCircle::IsValid(); } void TPGeCircle2D::TransformBy(const TGMatrix&matrix) { matrix.Transform2D(center); } TGObject * TPGeCircle2D::Clone() const { return new TPGeCircle2D(*this); } GRelation TPGeCircle2D::HitTest(const TGPoint& pt) const { return TPGeCircle::HitTest(pt); } double TPGeCircle2D::Integration(double pa0,double pa1) const { if (Is(CLOCKWISE_CURVE)) { return TPGeCircle::Integration(PI2 - pa0, PI2 - pa1); } else { return TPGeCircle::Integration(pa0, pa1); } } bool TPGeCircle2D::Intersect(const TGObject& obj, TGObjectList& res) const { switch(obj.GetClassID()) { case CID_GLine2D: { TGPoint2D* pPt1 = new TGPoint2D, *pPt2 = new TGPoint2D; int ret = TPGeCircle::Intersect((const TPGeGLine2D&)obj,*pPt1,*pPt2); if (ret == INT_NULL) { delete pPt1; delete pPt2; return false; } else if (ret == INT_2PT) { res << pPt1 << pPt2; } else { res << pPt1; delete pPt2; } return true; } case CID_GLineRay2D: { double pa1,pa2; const TPGeGLineRay2D& ray = (const TPGeGLineRay2D&)obj; const TPGeLine2D& line = ray; int ret = line.Intersect(this,pa1,pa2); if (ret == INT_NULL) { return false; } else if (ret == INT_2PT) { bool result = false; if (UPEQUAL_ZERO(pa1)) { TGPoint2D* pPt = new TGPoint2D; ray.Pa2Pt(pa1,*pPt); res << pPt; result = true; } if (UPEQUAL_ZERO(pa2)) { TGPoint2D* pPt = new TGPoint2D; ray.Pa2Pt(pa2,*pPt); res << pPt; result = true; } return result; } else { if (UPEQUAL_ZERO(pa1)) { TGPoint2D* pPt = new TGPoint2D; ray.Pa2Pt(pa1,*pPt); res << pPt; return true; } return false; } } case CID_GLineSeg2D: { double pa1,pa2; const TPGeGLineSeg2D& seg = (const TPGeGLineSeg2D&)obj; const TPGeLine2D& line = seg; int ret = line.Intersect(this,pa1,pa2); if (ret == INT_NULL) { return false; } else if (ret == INT_2PT) { bool result = false; if (UPEQUAL_ZERO(pa1) && DOWNEQUAL_ZERO(pa1 - 1)) { TGPoint2D* pPt = new TGPoint2D; seg.Pa2Pt(pa1,*pPt); res << pPt; result = true; } if (UPEQUAL_ZERO(pa2) && DOWNEQUAL_ZERO(pa2 - 1)) { TGPoint2D* pPt = new TGPoint2D; seg.Pa2Pt(pa2,*pPt); res << pPt; result = true; } return result; } else { if (UPEQUAL_ZERO(pa1) && DOWNEQUAL_ZERO(pa1 - 1)) { TGPoint2D* pPt = new TGPoint2D; seg.Pa2Pt(pa1,*pPt); res << pPt; return true; } return false; } } case CID_GCircle2D: { TGPoint2D* pPt1 = new TGPoint2D,*pPt2 = new TGPoint2D; int ret = TPGeCircle::Intersect((const TPGeCircle2D&)obj,*pPt1,*pPt2); if (ret == INT_NULL) { delete pPt1; delete pPt2; return false; } else if (ret == INT_2PT) { res << pPt1 << pPt2; } else if (ret == INT_1PT) { res << pPt1; delete pPt2; } else { delete pPt1; delete pPt2; res << new TPGeCircle2D(*this); } return true; } default: return obj.Intersect(*this,res); } } bool TPGeCircle2D::IsInclude(const TGObject& obj) const { switch(obj.GetClassID()) { case CID_GLine2D: case CID_GLineRay2D: case CID_GLineSeg2D: return false; case CID_GArc2D: return IsSameCircle(((const TPGeArc2D&)obj).circle); case CID_GCircle2D: return IsSameCircle((const TPGeCircle2D&)obj); default: return TPGeCurve2D::IsInclude(obj); } } bool TPGeCircle2D::GetExtend2D(TPGeExtend2D&ext) const { ext.SetRange(center.x - r,center.x + r, center.y - r, center.y + r); return true; } TPGeCurve2D* TPGeCircle2D::GetSubCurve(double pa0,double pa1) const { TPGeArc2D* pArc = new TPGeArc2D(*this); pArc->SetStartAngle(pa0); pArc->centralAngle = NA(pa1 - pa0); if (DOWNEQUAL_ZEROA(pArc->centralAngle)) { pArc->centralAngle = PI2; } return pArc; } TGMLine2D* TPGeCircle2D::PLinearize(double paDist) const { return new TGPLine2D(*this); } void TPGeCircle2D::Split(const TTable& paTable, TGObjectList& res) const { if (paTable.IsEmpty()) { return; } if (paTable.GetLength() == 1) { res << GetSubCurve(paTable.GetAt(0),paTable.GetAt(0)); } else { for (long i = 1; i < paTable.GetLength(); i++) { if (DOWN_ZEROA(paTable.GetAt(i - 1) - paTable.GetAt(i))) { res << GetSubCurve(paTable.GetAt(i - 1), paTable.GetAt(i)); } } double last = paTable.GetAt(i - 1); if (DOWN_ZEROA(last - PI2) || UP_ZEROA(paTable.GetAt(0))) { res << GetSubCurve(last,paTable.GetAt(0)); } } } TGMLine2D* TPGeCircle2D::MLinearize(double paDist) const { if (paDist < 1E-9) { paDist = GetMLinePrec(); } long num = (long)(PI2 / paDist + 0.999999); if (num < 2) { return NULL; } paDist = PI2 / num; TGMLine2D *pMLine = new TGMLine2D(num,true); double pa = 0; for (long i = 0; i < num; i++, pa += paDist) { Pa2Pt(pa,(*pMLine)[i]); } return pMLine; } void TPGeCircle2D::Init(const TGPoint& pt0,const TGPoint& pt1,const TGPoint& pt2) { TPGeCircle::Init(pt0,pt1,pt2); if (TGVector2D(pt0,pt1).IsVectorRight(TGVector2D(pt1,pt2))) { AddFlag(CLOCKWISE_CURVE); } else { RemoveFlag(CLOCKWISE_CURVE); } } void TPGeCircle2D::Init(const TGPoint& pt0,const TGPoint& pt1,double angle) { TPGeCircle::Init(pt0,pt1,angle); if (angle < 0) { AddFlag(CLOCKWISE_CURVE); } else { RemoveFlag(CLOCKWISE_CURVE); } } bool TPGeCircle2D::IsSameCircle(const TPGeCircle2D& cir, bool bSameDirection) const { if (TPGeCircle::operator == (cir)) { if (bSameDirection) { return (Is(CLOCKWISE_CURVE) && cir.Is(CLOCKWISE_CURVE)) || (IsNot(CLOCKWISE_CURVE) && cir.IsNot(CLOCKWISE_CURVE)); } return true; } return false; }