//-------------------------------------------------------------------------------------------------------+ // Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd. // = FileName : TPGeArc2D 类 // = Version : ver2.0 // = Author : wlw // = CreateDate : 2002-09-09 // = Description: TPGeArc2D 定义 // = Maintainers: // //-------------------------------------------------------------------------------------------------------+ #include "StdAfx.h" #include "TPGeArc2D.h" // #include "TchGeLib.h" #include "TGPoint2D.h" #include "TWPushVar.h" IMPLEMENT_RUN_TIME_CLASS1(TPGeArc2D,"TPGeArc2D",TPGeCurve2D) TPGeArc2D::TPGeArc2D() { } TPGeArc2D::TPGeArc2D(const TGPoint&pt,double radius,double sA,double cA,bool bUnClockWise): circle(pt,radius,bUnClockWise),startAngle(sA),centralAngle(cA) { } TPGeArc2D::TPGeArc2D(const TGPoint&sPt,const TGPoint&ePt,double angle) { Init(sPt,ePt,angle); } TPGeArc2D::TPGeArc2D(const TGPoint&pt0,const TGPoint&pt1,const TGPoint&pt2) { Init(pt0,pt1,pt2); } TPGeArc2D::TPGeArc2D(const TPGeCircle2D& c):circle(c) { } TPGeCurve2D* TPGeArc2D::GetExtendCurve() const { return new TPGeCircle2D(circle); } bool TPGeArc2D::IsValid() const { return circle.IsValid() && UP_ZEROA(centralAngle) && DOWNEQUAL_ZEROA(centralAngle - PI2); } GRelation TPGeArc2D::HitTest(const TGPoint&pt) const { GRelation r = circle.HitTest(pt); if(r.Is(GR_IN)) { double pa; Pt2Pa(pt,pa); if(!IsParaInSeg(pa,GetParaPrecFromLength(Length())) && UP_ZEROD(Distance2D(GetStartPoint(),pt)) && UP_ZEROD(Distance2D(GetEndPoint(),pt))) { return GR_OUT; } } return r; } void TPGeArc2D::Reverse() { circle.Reverse(); startAngle = RA(GetEndAngle()); } void TPGeArc2D::GetStartPoint(TGPoint&pt) const { circle.Pa2Pt(startAngle,pt); } void TPGeArc2D::GetEndPoint(TGPoint&pt) const { circle.Pa2Pt(startAngle+centralAngle,pt); } void TPGeArc2D::Pt2Pa(const TGPoint&pt,double&pa) const { circle.Pt2Pa(pt,pa); pa = ALEN(startAngle,pa) / centralAngle; } void TPGeArc2D::Pa2Pt(double pa,TGPoint&pt) const { if(EQUAL_ZERO(pa)) { GetStartPoint(pt); } else if(EQUAL_ZERO(pa-1)) { GetEndPoint(pt); } else { circle.Pa2Pt(startAngle+pa*centralAngle,pt); } } double TPGeArc2D::Integration(double pa0,double pa1) const { return circle.Integration(pa0 * centralAngle + startAngle, pa1 * centralAngle + startAngle); } void TPGeArc2D::GetTangent(double pa,TPGeLine2D&line) const { circle.GetTangent(startAngle + pa * centralAngle, line); } bool TPGeArc2D::IsClosed() const { double d = PI2 - centralAngle; return EQUAL_ZEROA(d); } bool TPGeArc2D::Intersect(const TGObject&obj,TGObjectList&res) const { switch(obj.GetClassID()) { case CID_GLine2D: case CID_GLineRay2D: case CID_GLineSeg2D: { TGObjectList buf; if(circle.Intersect(obj,buf)) { double pa; double paraPrec = GetParaPrecFromLength(Length()); for(buf.MoveToFirst();!buf.IsOut();buf.MoveToNext()) { Pt2Pa((const TGPoint2D&)(buf.GetCurPData()),pa); if(!IsParaInSeg(pa,paraPrec)) { buf.DelCur(); } } if(!buf.IsEmpty()) { res.Conbine(buf); return true; } } return false; } case CID_GCircle2D: { TGObjectList buf; if(circle.Intersect(obj,buf)) { if(IS_TYPE(buf[0],TPGeCircle2D)) { res< vTemp(g_angleZero,GetAnglePrecFromRadius(circle.r)); if(((TPGeArc2D&)obj).IsClosed()) { res<circle.IsNot(CLOCKWISE_CURVE)) || (circle.IsNot(CLOCKWISE_CURVE) && pArc->circle.Is(CLOCKWISE_CURVE))) { pArc->Reverse(); } double sA = ALEN(startAngle,pArc->startAngle); double eA = ALEN(startAngle,pArc->GetEndAngle()); if(sA < eA) { double da = sA-centralAngle; if(UP_ZEROA(da)) { return false; } else if(DOWN_ZEROA(da)) { if(UP_ZEROA(eA - centralAngle)) { pArc->centralAngle = -da; } res.Conbine(buf); } else { res<centralAngle = eA; res<centralAngle = -da0; res.Conbine(buf); } else if(EQUAL_ZEROA(da0)) { res< 0.1) { newAngPrec = 0.1; } else if (newAngPrec < 1E-18) { newAngPrec = 1E-18; } return newAngPrec; } double TPGeArc2D::GetParaPrecFromLength(double dlength)const { double newPrec = g_distZero / dlength; if (newPrec > 0.1) { newPrec = 0.1; } else if (newPrec < 1E-18) { newPrec = 1E-18; } return newPrec; } bool TPGeArc2D::IsParaInSeg(double dpa,double dprec)const { TWPushVar vTemp(g_fZero,dprec); return UPEQUAL_ZERO(dpa) && DOWNEQUAL_ZERO(dpa - 1); }