282 lines
5.7 KiB
C++
282 lines
5.7 KiB
C++
//-------------------------------------------------------------------------------------------------------+
|
|
// 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;
|
|
}
|
|
}
|