//-----------------------------------------------------------------------------+ // 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; }