Files
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

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 &center,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 &center,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 &center1,double r1, const TGPoint &center2,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;
}
}