Files
envi-code/SourceCode/Code2026/AdsXRx/XCircle.cpp
T
2026-09-28 15:28:50 +08:00

436 lines
7.7 KiB
C++

//-----------------------------------------------------------------------------+
// Copyright (C), 1998-2007, SH Software Co. Ltd.
// = FileName : XCircle Àà
// = Version : ver2.0
// = Author : zjq
// = CreateDate : 2002-09-09
// = Description: XCircle ÀඨÒå
// = Maintainers:
//
//-----------------------------------------------------------------------------+
#include "StdAfx.h"
#include "XCircle.h"
#include "XLine.h"
#include "Entity.h"
#include "XArc.h"
#include "XGlobalFunc.h"
#include "XPrivateGlobalFunc.h"
#include "XGlobalCurveFunc.h"
#include "XCurveInline.h"
XCircle::XCircle()
{
}
XCircle::XCircle(const XCircle &src)
{
m_ptCenter = src.m_ptCenter;
m_dRadius = src.m_dRadius;
}
XCircle::XCircle(const XPoint &startPoint, const XPoint &pt2, const XPoint &endPoint)
:m_dRadius(0.0)
{
AcGeCircArc3d cir(startPoint,pt2,endPoint);
m_ptCenter = cir.center();
m_dRadius = cir.radius();
}
XCircle::XCircle(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;
}
XCircle::XCircle(const ads_point ptcenter, double dradius)
{
m_ptCenter = ptcenter;
m_dRadius = dradius;
}
XCircle::XCircle(const Entity& entCircle, ads_matrix mat)
{
Entity entCirTemp = entCircle;
entCirTemp.GetData(10, m_ptCenter);
entCirTemp.GetData(40, &m_dRadius);
if (mat)
{
XPoint pt;
ads_polar(m_ptCenter, 0, m_dRadius, pt);
m_ptCenter.TransformBy(mat);
pt.TransformBy(mat);
m_dRadius = ads_distance(m_ptCenter, pt);
}
}
XCircle::~XCircle()
{
}
void XCircle::Set(const XPoint &diaPt1, const XPoint &diaPt2)
{
ads_point ptcen;
Midpoint(diaPt1, diaPt2, ptcen);
m_ptCenter = ptcen;
m_dRadius = ads_distance(diaPt1, diaPt2) / 2.0;
}
ShapeType XCircle::GetShapeType() const
{
return SHAPE_CIRCLE;
}
void XCircle::Center(ads_point ptCen)
{
m_ptCenter > ptCen;
}
int XCircle::HitTest2d(const XPoint &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 XCircle::Intersection(const XLine* pLine, ads_point ptrp1, ads_point ptrp2) const
{
ASSERT(pLine != NULL);
return pLine->Intersection(this, ptrp1, ptrp2);
}
int XCircle::Intersection(const XArc* pArc, ads_point ptrp1, ads_point ptrp2) const
{
ASSERT(pArc != NULL);
AcGeCircArc3d cirT(m_ptCenter.AsAcGePoint3d(),
AcGeVector3d::kZAxis,m_dRadius);
AcGeCircArc3d cirO(pArc->m_ptCenter.AsAcGePoint3d(),AcGeVector3d::kZAxis,pArc->m_dRadius);
int nInt = 0;
XPoint 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 XCircle::Intersection(const XCircle* 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;
}
//ͬÐÄ
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;
XPoint 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 XCircle::Make(const TCHAR *szlay) const
{
TCHAR szlayer[80] = _T("");
if (szlay)
{
_tcscpy(szlayer, szlay);
}
else
{
xg_getvar(_T("clayer"), szlayer);
}
return XExport::MakeEntity(RTDXF0, _T("CIRCLE"), 8, szlayer, 10, &m_ptCenter.x, 40, m_dRadius, NULL);
}
int XCircle::Modify(const Entity* pEntity) const
{
ASSERT(pEntity != NULL);
Entity refEnt = *pEntity;
refEnt.SetData(10, &m_ptCenter.x);
refEnt.SetData(40, m_dRadius);
return refEnt.Modify();
}
int XCircle::MakeEntity(const Entity* pEntity) const
{
ASSERT(pEntity != NULL);
Entity ent = *pEntity;
Groups g(_T("*"));
RBList ebuf = ads_entgetx(ent, (resbuf *)&g);
ebuf.SetData(10, &m_ptCenter.x);
ebuf.SetData(40, m_dRadius);
return ads_entmake(ebuf);
}
int XCircle::GetSubArc(const XPoint& ptloc, ads_real dchordLen, XArc& 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(CT_std_angle(ads_angle(m_ptCenter, ptloc) - dsemiAng));
arcres.SetEndAngle(CT_std_angle(ads_angle(m_ptCenter, ptloc) + dsemiAng));
return RTNORM;
}
int XCircle::OSnap(int nMode, XPoint &ptPick) const
{
switch(nMode)
{
case OS_CEN:
ptPick = m_ptCenter;
return nMode;
case OS_NEA:
XPoint ptSrc = ptPick;
if (ptSrc.Project(this, ptPick) == RTNORM)
{
return nMode;
}
break;
}
return OS_NON;
}
void XCircle::TransUCS(ads_matrix mat)
{
XPoint 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 XCircle::PtOnCircle(const XPoint &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;
}
XPoint XCircle::GetCenterPt()
{
return m_ptCenter;
}
XPoint XCircle::GetCenterPt() const
{
return m_ptCenter;
}
void XCircle::SetCenterPt(XPoint pt)
{
m_ptCenter = pt;
}
double XCircle::GetRadius() const
{
return m_dRadius;
}
bool XCircle::Set(const XPoint &ptStart, const XPoint &ptOn, const XPoint &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 XCircle::GetRadius()
{
return m_dRadius;
}
void XCircle::SetRadius(double dR)
{
m_dRadius = dR;
}
bool XCircle::IsKindOf(XEntity::TEntityId entType) const
{
switch(entType)
{
case XEntity::eEntity:
case XEntity::eCurve:
case XEntity::eCircle:
return true;
}
return false;
}
void XCircle::CopyFrom(const XEntity* pSrc)
{
if (this != pSrc && pSrc->IsKindOf(XEntity::eCircle))
{
XCircle* pArc = (XCircle* )pSrc;
m_ptCenter = pArc->GetCenterPt();
m_dRadius = pArc->GetRadius();
}
}
int XCircle::operator !() const
{
return m_dRadius < XGeLib::_DIST_SNAP;
}
XCircle& XCircle::operator = (const XCircle &src)
{
if (this != &src)
{
m_ptCenter = src.GetCenterPt();
m_dRadius = src.GetRadius();
}
return *this;
}
bool XCircle::operator == (const XCircle &src) const
{
return (m_ptCenter == src.GetCenterPt()
&& fabs(m_dRadius - src.GetRadius()) < XGeLib::_DIST_SNAP);
}
ads_real XCircle::GetLength() const
{
return m_dRadius * 2.0 * PI;
}
XCircle XCircle::Offset(ads_real dist) const
{
double dRadius = m_dRadius;
dRadius = dRadius + dist;
if (dRadius < XGeLib::_DIST_SNAP)
{
dRadius = 0.0;
}
return XCircle(m_ptCenter, dRadius);
}
ads_real XCircle::Area() const
{
double dRadius = m_dRadius;
return PI * dRadius * dRadius;
}
int XCircle::GetExtend(ads_point lowPt, ads_point upPt) const
{
XPoint ptCenter = m_ptCenter;
double dRadius = m_dRadius;
*(XPoint*)lowPt = ptCenter - XPoint(dRadius, dRadius);
*(XPoint*)upPt = ptCenter + XPoint(dRadius, dRadius);
return RTNORM;
}