//-------------------------------------------------------------------------------------------------------+ // Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd. // = FileName : TPGeCircle 类 无向圆 // = Version : ver2.0 // = Author : wlw // = CreateDate : 2002-09-09 // = Description: TPGeCircle 定义 // = Maintainers: // //-------------------------------------------------------------------------------------------------------+ #include "StdAfx.h" #include "TPGeCircle.h" TPGeCircle::TPGeCircle() { } TPGeCircle::TPGeCircle(const TGPoint& pt,double radius) : center(pt),r(radius) { } TPGeCircle::TPGeCircle(const TGPoint& pt0,const TGPoint& pt1,const TGPoint& pt2) { Init(pt0,pt1,pt2); } TPGeCircle::~TPGeCircle() { } TPGeCircle::TPGeCircle(const TGPoint& pt0,const TGPoint& pt1,double angle) { Init(pt0,pt1,angle); } void TPGeCircle::Init(const TGPoint& pt0,const TGPoint& pt1,const TGPoint& pt2) { InitCircle2D(pt0,pt1,pt2,center,r); } void TPGeCircle::Init(const TGPoint& pt0,const TGPoint& pt1,double angle) { InitCircle2D(pt0,pt1,angle,center,r); } bool TPGeCircle::IsValid() const { return UP_ZEROD(r); } void TPGeCircle::GetDirection(const TGPoint& pt,TGPoint& vt) const { TGVector2D(center,pt).GetLVertVector(vt); } void TPGeCircle::GetDirection(double pa,TGPoint& vt) const { TGPoint pt;Pa2Pt(pa,pt); GetDirection(pt,vt); } void TPGeCircle::GetTangent(double pa,TPGeLine2D& line) const { Pa2Pt(pa,line.basePoint); GetDirection(line.basePoint,line); line.Normalize(); } void TPGeCircle::Pt2Pa(const TGPoint& pt,double& pa) const { pa = TGVector2D(center,pt).GetAngle(); } void TPGeCircle::Pa2Pt(double pa,TGPoint& pt) const { pt.x = center.x+r*cos(pa); pt.y = center.y+r*sin(pa); pt.z = center.z; } double TPGeCircle::Length() const { return PI2*r; } double TPGeCircle::Area() const { return PI*r*r; } bool TPGeCircle::operator != (const TPGeCircle& c) const { return !(*this == c); } double TPGeCircle::Integration(double pa0,double pa1) const { return CircleIntegration2D(center,r,pa0,pa1); } int TPGeCircle::HitTest(const TGPoint& pt) const { double temp = Distance2D(center,pt) - r; if(UP_ZEROD(temp)) { return GR_OUTSIDE; } else if(DOWN_ZEROD(temp)) { return GR_INSIDE; } else { return GR_IN; } } bool TPGeCircle::Offset(double nDist) { double newRadius = r + nDist; if(DOWNEQUAL_ZERO(newRadius)) { return false; } r = newRadius; return true; } bool TPGeCircle::operator == (const TPGeCircle& c) const { double temp = r - c.r; return EQUAL_ZEROD(temp) && center.Equal2D(c.center); } int TPGeCircle::Intersect(const TPGeCircle& circle,TGPoint& pt1,TGPoint& pt2) const { return CircleInt(center,r,circle.center,circle.r,pt1,pt2); } int TPGeCircle::Intersect(const TPGeLine2D& line,TGPoint& pt1,TGPoint& pt2,bool bNormalized) const { if(bNormalized) { return LineCirInt2D(center,r,line.basePoint,line,pt1,pt2); } TGVector2D vt(line); vt.Normalize(); return LineCirInt2D(center,r,line.basePoint,vt,pt1,pt2); } void TPGeCircle::InitCircle2D(const TGPoint &pt0,const TGPoint &pt1,const TGPoint &pt2,TGPoint ¢er,double &r) { double pa; TGVector2D vt0,vt1; TGVector2D(pt0,pt1).GetLVertVector(vt0); vt0.Normalize(); TGVector2D(pt1,pt2).GetLVertVector(vt1); vt1.Normalize(); TGPoint pt00((pt0.x + pt1.x) / 2,(pt0.y + pt1.y) / 2),pt11((pt1.x + pt2.x) / 2,(pt1.y + pt2.y) / 2); LineInt2D(pt00,vt0,pt11,vt1,pa); LinePt2D(pt0,vt0,pa,center); r = Distance2D(center,pt0); } void TPGeCircle::InitCircle2D(const TGPoint &pt0,const TGPoint &pt1,double angle,TGPoint ¢er,double &r) { double len = Distance2D(pt0,pt1); r = fabs(len / (2 * sin(angle / 2))); TGVector2D vt0(pt0,pt1),vt; vt0.GetLVertVector(vt); vt.SetLength(fabs(r * cos(angle / 2))); center.x = (pt0.x + pt1.x) / 2; center.y = (pt0.y + pt1.y) / 2; center.z = pt0.z; if ((UP_ZEROA(angle) && (DOWN_ZEROA(angle - PI))) || DOWN_ZEROA(angle + PI)) { center.x += vt.x; center.y += vt.y; } else if ((DOWN_ZEROA(angle) && UP_ZEROA(angle + PI)) || UP_ZEROA(angle - PI)) { center.x -= vt.x; center.y -= vt.y; } } int TPGeCircle::CircleInt(const TGPoint ¢er1,double r1, const TGPoint ¢er2,double r2, TGPoint &pt1,TGPoint &pt2)const { TGVector2D vt(center1,center2); if (vt.IsNullVector()) { double temp = r1 - r2; if (EQUAL_ZEROD(temp)) { return INT_CIRCLE; } else { return INT_NULL; } } else { double dist = vt.Length(); double dist1 = dist - fabs(r1 - r2); if (DOWN_ZEROD(dist1)) { return INT_NULL; } double dist2 = dist - r1 - r2; if (UP_ZEROD(dist2)) { return INT_NULL; } if (EQUAL_ZEROD(dist1)) { vt *= r1 > r2 ? (r1 / dist) : (-r1 / dist); pt1.x = center1.x + vt.x; pt1.y = center1.y + vt.y; pt1.z = center1.z; return INT_1PT; } if (EQUAL_ZEROD(dist2)) { vt *= (r1 / dist); pt1.x = center1.x + vt.x; pt1.y = center1.y + vt.y; pt1.z = center1.z; return INT_1PT; } double r12 = r1 * r1, r22 = r2 * r2, d2 = dist * dist; if (r1 >= r2) { double cos = (r12 + d2 - r22) / (2 * r1 * dist); double sin = sqrt(1 - cos * cos); TGVector2D vt1; vt.GetLVertVector(vt1); vt.SetLength(r1 * cos); vt1.SetLength(r1 * sin); pt1.x = center1.x + vt.x + vt1.x; pt1.y = center1.y + vt.y + vt1.y; pt2.x = center1.x + vt.x - vt1.x; pt2.y = center1.y + vt.y - vt1.y; } else { double cos = (r22 + d2 - r12) / (2 * r2 * dist); double sin = sqrt(1 - cos * cos); TGVector2D vt1; vt.Reverse(); vt.GetLVertVector(vt1); vt.SetLength(r2 * cos); vt1.SetLength(r2 * sin); pt1.x = center2.x + vt.x + vt1.x; pt1.y = center2.y + vt.y + vt1.y; pt2.x = center2.x + vt.x - vt1.x; pt2.y = center2.y + vt.y - vt1.y; } pt1.z = center1.z; pt2.z = center1.z; return INT_2PT; } }