439 lines
8.2 KiB
C++
439 lines
8.2 KiB
C++
//-----------------------------------------------------------------------------+
|
|
// Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd.
|
|
// = FileName : TGGeCircle 类
|
|
// = Version : ver2.0
|
|
// = Author : wlw
|
|
// = CreateDate : 2002-09-09
|
|
// = Description: TGGeCircle 类定义
|
|
// = Maintainers:
|
|
//
|
|
//-----------------------------------------------------------------------------+
|
|
#include "StdAfx.h"
|
|
#include "TGGeCircle.h"
|
|
#include "TGGeLine.h"
|
|
#include "TEntitySet.h"
|
|
#include "TGGeArc.h"
|
|
#include "TchGlobalFunc.h"
|
|
#include "TchPrivateGlobalFunc.h"
|
|
#include "TchGlobalCurveFunc.h"
|
|
#include "TGGeCurveInline.h"
|
|
|
|
TGGeCircle::TGGeCircle()
|
|
{
|
|
|
|
}
|
|
|
|
TGGeCircle::TGGeCircle(const TGGeCircle &src)
|
|
{
|
|
m_ptCenter = src.m_ptCenter;
|
|
m_dRadius = src.m_dRadius;
|
|
}
|
|
|
|
TGGeCircle::TGGeCircle(const TADSGePoint3d &startPoint, const TADSGePoint3d &pt2, const TADSGePoint3d &endPoint)
|
|
:m_dRadius(0.0)
|
|
{
|
|
AcGeCircArc3d cir(startPoint,pt2,endPoint);
|
|
m_ptCenter = cir.center();
|
|
m_dRadius = cir.radius();
|
|
}
|
|
|
|
TGGeCircle::TGGeCircle(const ads_point diaPt1, const ads_point diaPt2)
|
|
{
|
|
ads_point ptcen;
|
|
Midpoint(diaPt1, diaPt2, ptcen);
|
|
|
|
m_ptCenter = ptcen;
|
|
m_dRadius = ads_distance(diaPt1, diaPt2) / 2.0;
|
|
}
|
|
|
|
TGGeCircle::TGGeCircle(const ads_point ptcenter, double dradius)
|
|
{
|
|
m_ptCenter = ptcenter;
|
|
m_dRadius = dradius;
|
|
}
|
|
|
|
TGGeCircle::TGGeCircle(const TEntitySet& entCircle, ads_matrix mat)
|
|
{
|
|
TEntitySet entCirTemp = entCircle;
|
|
entCirTemp.GetData(10, m_ptCenter);
|
|
entCirTemp.GetData(40, &m_dRadius);
|
|
|
|
if (mat)
|
|
{
|
|
TADSGePoint3d pt;
|
|
ads_polar(m_ptCenter, 0, m_dRadius, pt);
|
|
m_ptCenter.TransformBy(mat);
|
|
pt.TransformBy(mat);
|
|
m_dRadius = ads_distance(m_ptCenter, pt);
|
|
}
|
|
}
|
|
|
|
TGGeCircle::~TGGeCircle()
|
|
{
|
|
|
|
}
|
|
|
|
void TGGeCircle::Set(const TADSGePoint3d &diaPt1, const TADSGePoint3d &diaPt2)
|
|
{
|
|
ads_point ptcen;
|
|
Midpoint(diaPt1, diaPt2, ptcen);
|
|
|
|
m_ptCenter = ptcen;
|
|
m_dRadius = ads_distance(diaPt1, diaPt2) / 2.0;
|
|
}
|
|
|
|
ShapeType TGGeCircle::GetShapeType() const
|
|
{
|
|
return SHAPE_CIRCLE;
|
|
}
|
|
|
|
void TGGeCircle::Center(ads_point ptCen)
|
|
{
|
|
m_ptCenter > ptCen;
|
|
}
|
|
|
|
int TGGeCircle::HitTest2d(const TADSGePoint3d &ptTest) const
|
|
{
|
|
double dDist2d = ptTest.Distance2d(m_ptCenter);
|
|
if (fabs(dDist2d - m_dRadius) < _DIST_SNAP)
|
|
{
|
|
return 5;
|
|
}
|
|
|
|
if (dDist2d < m_dRadius)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
return 2;
|
|
}
|
|
|
|
int TGGeCircle::Intersection(const TGGeLine* pLine, ads_point ptrp1, ads_point ptrp2) const
|
|
{
|
|
ASSERT(pLine != NULL);
|
|
return pLine->Intersection(this, ptrp1, ptrp2);
|
|
}
|
|
|
|
int TGGeCircle::Intersection(const TGGeArc* pArc, ads_point ptrp1, ads_point ptrp2) const
|
|
{
|
|
ASSERT(pArc != NULL);
|
|
AcGeCircArc3d cirT(m_ptCenter.AsAcGePoint3d(),
|
|
AcGeVector3d::kZAxis,m_dRadius);
|
|
|
|
//lfy 2010-08-31 修改存取方式
|
|
AcGeCircArc3d cirO(pArc->m_ptCenter.AsAcGePoint3d(),AcGeVector3d::kZAxis,pArc->m_dRadius);
|
|
|
|
int nInt = 0;
|
|
TADSGePoint3d pt1, pt2;
|
|
|
|
cirT.intersectWith(cirO,nInt,pt1,pt2);
|
|
if (nInt == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int nt1,nt2;
|
|
nt1 = ((pt1 & (*pArc)) != PR_OUTSIDE);
|
|
nt2 = ((pt2 & (*pArc)) != PR_OUTSIDE);
|
|
|
|
if (ptrp1)
|
|
{
|
|
if (nt1)
|
|
{
|
|
pt1 > ptrp1;
|
|
}
|
|
|
|
if (!nt1 && nt2)
|
|
{
|
|
pt2 > ptrp1;
|
|
}
|
|
}
|
|
|
|
if (ptrp2)
|
|
{
|
|
if (nt2 && nt1)
|
|
{
|
|
pt2 > ptrp2;
|
|
}
|
|
}
|
|
|
|
if (nt1 + nt2 == 2)
|
|
{
|
|
if (asPnt3d(ptrp1).distanceTo(asPnt3d(ptrp2)) < _DIST_SNAP)
|
|
{
|
|
nt2 = 0;
|
|
}
|
|
}
|
|
|
|
return nt1 + nt2;
|
|
|
|
}
|
|
|
|
int TGGeCircle::Intersection(const TGGeCircle* pCir, ads_point ptrp1, ads_point ptrp2) const
|
|
{
|
|
ASSERT(pCir != NULL);
|
|
if (!IsEqual(1.0E-5, 2, pCir->m_ptCenter.z, m_ptCenter.z))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
//lfy 2010-08-31 修改存取方式
|
|
//同心
|
|
if ( m_ptCenter.AsAcGePoint3d().distanceTo(pCir->m_ptCenter.AsAcGePoint3d()) < 1.e-3)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
AcGeCircArc3d cirT(m_ptCenter.AsAcGePoint3d(),AcGeVector3d::kZAxis,m_dRadius);
|
|
AcGeCircArc3d cirO(pCir->m_ptCenter.AsAcGePoint3d(),AcGeVector3d::kZAxis,pCir->m_dRadius);
|
|
|
|
int nInt = 0;
|
|
TADSGePoint3d pt1, pt2;
|
|
|
|
cirT.intersectWith(cirO,nInt,pt1,pt2);
|
|
if (nInt == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if (ptrp1)
|
|
{
|
|
pt1 > ptrp1;
|
|
}
|
|
|
|
if (ptrp2)
|
|
{
|
|
pt2 > ptrp2;
|
|
}
|
|
|
|
if (asPnt3d(ptrp1).distanceTo(asPnt3d(ptrp2)) < _DIST_SNAP)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
return 2;
|
|
}
|
|
|
|
int TGGeCircle::Make(const TCHAR *szlay) const
|
|
{
|
|
TCHAR szlayer[80] = _T("");
|
|
if (szlay)
|
|
{
|
|
_tcscpy(szlayer, szlay);
|
|
}
|
|
else
|
|
{
|
|
TGGetVar(_T("clayer"), szlayer);
|
|
}
|
|
|
|
return TchExport::MakeEntity(RTDXF0, _T("CIRCLE"), 8, szlayer, 10, &m_ptCenter.x, 40, m_dRadius, NULL);
|
|
}
|
|
|
|
int TGGeCircle::Modify(const TEntitySet* pEntity) const
|
|
{
|
|
ASSERT(pEntity != NULL);
|
|
TEntitySet refEnt = *pEntity;
|
|
refEnt.SetData(10, &m_ptCenter.x);
|
|
refEnt.SetData(40, m_dRadius);
|
|
|
|
return refEnt.Modify();
|
|
}
|
|
|
|
int TGGeCircle::MakeEntity(const TEntitySet* pEntity) const
|
|
{
|
|
ASSERT(pEntity != NULL);
|
|
TEntitySet ent = *pEntity;
|
|
TGroups g(_T("*"));
|
|
TRBList ebuf = ads_entgetx(ent, (resbuf *)&g);
|
|
ebuf.SetData(10, &m_ptCenter.x);
|
|
ebuf.SetData(40, m_dRadius);
|
|
|
|
return ads_entmake(ebuf);
|
|
}
|
|
|
|
int TGGeCircle::GetSubArc(const TADSGePoint3d& ptloc, ads_real dchordLen, TGGeArc& arcres) const
|
|
{
|
|
if (m_dRadius < _DIST_SNAP
|
|
|| dchordLen > 2.0 * m_dRadius
|
|
|| (ptloc & (*this)) != PR_ONCIRCLE)
|
|
{
|
|
return RTERROR;
|
|
}
|
|
|
|
ads_real dsemiAng = asin(dchordLen / 2.0 / m_dRadius);
|
|
arcres.SetCenterPt(m_ptCenter);
|
|
arcres.SetRadius(m_dRadius);
|
|
arcres.SetStarAngle(AngleRangeTo2PI(ads_angle(m_ptCenter, ptloc) - dsemiAng));
|
|
arcres.SetEndAngle(AngleRangeTo2PI(ads_angle(m_ptCenter, ptloc) + dsemiAng));
|
|
|
|
return RTNORM;
|
|
}
|
|
|
|
int TGGeCircle::OSnap(int nMode, TADSGePoint3d &ptPick) const
|
|
{
|
|
switch(nMode)
|
|
{
|
|
case OS_CEN:
|
|
ptPick = m_ptCenter;
|
|
return nMode;
|
|
case OS_NEA:
|
|
TADSGePoint3d ptSrc = ptPick;
|
|
if (ptSrc.Project(this, ptPick) == RTNORM)
|
|
{
|
|
return nMode;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
return OS_NON;
|
|
}
|
|
|
|
void TGGeCircle::TransUCS(ads_matrix mat)
|
|
{
|
|
TADSGePoint3d ptOnEdge;
|
|
ads_polar(m_ptCenter, 0.0, m_dRadius, ptOnEdge);
|
|
m_ptCenter.TransformBy(mat);
|
|
ptOnEdge.z = m_ptCenter.z;
|
|
m_dRadius = ptOnEdge.Distance(m_ptCenter);
|
|
}
|
|
|
|
int TGGeCircle::PtOnCircle(const TADSGePoint3d &pt)
|
|
{
|
|
double r = pt.Distance(m_ptCenter) - m_dRadius;
|
|
if (fabs(r) < _DIST_SNAP)
|
|
{
|
|
return PR_ONCIRCLE;
|
|
}
|
|
|
|
if (r < 0)
|
|
{
|
|
return PR_INSIDE;
|
|
}
|
|
|
|
return PR_OUTSIDE;
|
|
}
|
|
|
|
TADSGePoint3d TGGeCircle::GetCenterPt()
|
|
{
|
|
return m_ptCenter;
|
|
}
|
|
|
|
TADSGePoint3d TGGeCircle::GetCenterPt() const
|
|
{
|
|
return m_ptCenter;
|
|
}
|
|
|
|
void TGGeCircle::SetCenterPt(TADSGePoint3d pt)
|
|
{
|
|
m_ptCenter = pt;
|
|
}
|
|
|
|
double TGGeCircle::GetRadius() const
|
|
{
|
|
return m_dRadius;
|
|
}
|
|
|
|
bool TGGeCircle::Set(const TADSGePoint3d &ptStart, const TADSGePoint3d &ptOn, const TADSGePoint3d &ptEnd)
|
|
{
|
|
AcGeVector3d v1 = ptStart - ptOn;
|
|
AcGeVector3d v2 = ptEnd - ptOn;
|
|
if (v2.isParallelTo(v1))
|
|
{
|
|
return false;
|
|
}
|
|
AcGeCircArc3d cir(ptStart,ptOn,ptEnd);
|
|
m_ptCenter = cir.center();
|
|
m_dRadius = cir.radius();
|
|
return true;
|
|
}
|
|
|
|
double TGGeCircle::GetRadius()
|
|
{
|
|
return m_dRadius;
|
|
}
|
|
|
|
void TGGeCircle::SetRadius(double dR)
|
|
{
|
|
m_dRadius = dR;
|
|
}
|
|
|
|
bool TGGeCircle::IsKindOf(TGGeEntity::TEntityId entType) const
|
|
{
|
|
switch(entType)
|
|
{
|
|
case TGGeEntity::eEntity:
|
|
case TGGeEntity::eCurve:
|
|
case TGGeEntity::eCircle:
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void TGGeCircle::CopyFrom(const TGGeEntity* pSrc)
|
|
{
|
|
if (this != pSrc && pSrc->IsKindOf(TGGeEntity::eCircle))
|
|
{
|
|
TGGeCircle* pArc = (TGGeCircle* )pSrc;
|
|
m_ptCenter = pArc->GetCenterPt();
|
|
m_dRadius = pArc->GetRadius();
|
|
}
|
|
}
|
|
|
|
|
|
int TGGeCircle::operator !() const
|
|
{
|
|
return m_dRadius < TchGeLib::_DIST_SNAP;
|
|
}
|
|
|
|
TGGeCircle& TGGeCircle::operator = (const TGGeCircle &src)
|
|
{
|
|
if (this != &src)
|
|
{
|
|
m_ptCenter = src.GetCenterPt();
|
|
m_dRadius = src.GetRadius();
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
bool TGGeCircle::operator == (const TGGeCircle &src) const
|
|
{
|
|
return (m_ptCenter == src.GetCenterPt()
|
|
&& fabs(m_dRadius - src.GetRadius()) < TchGeLib::_DIST_SNAP);
|
|
}
|
|
|
|
ads_real TGGeCircle::GetLength() const
|
|
{
|
|
return m_dRadius * 2.0 * PI;
|
|
}
|
|
|
|
TGGeCircle TGGeCircle::Offset(ads_real dist) const
|
|
{
|
|
double dRadius = m_dRadius;
|
|
dRadius = dRadius + dist;
|
|
if (dRadius < TchGeLib::_DIST_SNAP)
|
|
{
|
|
dRadius = 0.0;
|
|
}
|
|
|
|
return TGGeCircle(m_ptCenter, dRadius);
|
|
}
|
|
|
|
ads_real TGGeCircle::Area() const
|
|
{
|
|
double dRadius = m_dRadius;
|
|
return PI * dRadius * dRadius;
|
|
}
|
|
|
|
int TGGeCircle::GetExtend(ads_point lowPt, ads_point upPt) const
|
|
{
|
|
TADSGePoint3d ptCenter = m_ptCenter;
|
|
double dRadius = m_dRadius;
|
|
*(TADSGePoint3d*)lowPt = ptCenter - TADSGePoint3d(dRadius, dRadius);
|
|
*(TADSGePoint3d*)upPt = ptCenter + TADSGePoint3d(dRadius, dRadius);
|
|
|
|
return RTNORM;
|
|
}
|
|
|