//-----------------------------------------------------------------------------+ // Copyright (C), 1998-2007, SH Software Co. Ltd. // = FileName : XArc 弧类 // = Version : ver2.0 // = Author : zjq // = CreateDate : 2002-09-09 // = Description: XArc 类定义 // = Maintainers: // //-----------------------------------------------------------------------------+ #include "StdAfx.h" #include "XArc.h" #include "XLine.h" #include "Entity.h" #include "XGlobalFunc.h" #include "XPrivateGlobalFunc.h" #include "XGlobalCurveFunc.h" #include "XCurveInline.h" XArc::XArc() { } XArc::XArc(const XArc &src) : XCircle(src), XSector(src) { } XArc::XArc(const Entity &aCircle) : XCircle(aCircle), XSector(aCircle) { } XArc::XArc(ads_point ptcenter, double dradius, double ptstartAngle, double ptendAngle) :XCircle(ptcenter,dradius) { m_dstartAngle = ptstartAngle; m_dendAngle = ptendAngle; } XArc::XArc(const XPoint &spt, const XPoint &ept, ads_real dang) { Set(spt,ept,dang); } XArc::XArc(const Entity &xarc, ads_matrix mat) : XCircle(xarc), XSector(xarc) { if (mat) { //zjq 2009-08-31 修改存取方式 XPoint spt, ept, ptCenter; ptCenter = GetCenterPt(); ads_polar(m_ptCenter, m_dstartAngle, m_dRadius, spt); ads_polar(m_ptCenter, m_dendAngle, m_dRadius, ept); ptCenter.TransformBy(mat); spt.TransformBy(mat); ept.TransformBy(mat); SetCenterPt(ptCenter); m_dstartAngle = ads_angle(ptCenter, spt); m_dendAngle = ads_angle(ptCenter, ept); m_dRadius = ads_distance(ptCenter, spt); } } XArc::XArc(const XPoint &startPoint, const XPoint &pt2, const XPoint &endPoint) :XCircle(startPoint, pt2, endPoint) { XCircle &cir = *this; if(!cir) { return; } //Set(startPoint, pt2, endPoint); SetAngleByPoints(startPoint, endPoint); if ((pt2 & (*this)) != PR_INSIDE) { //Set(endPoint, pt2, startPoint); SetAngleByPoints(endPoint, startPoint); } } XArc::~XArc() { } bool XArc::Set(const XPoint &spt, const XPoint &ept, ads_real dang) { ads_real ddis = ads_distance(spt, ept) / 2.0; ads_real dangTmp = fabs(dang / 2.0); m_dRadius = ddis / sin(dangTmp); ads_real dcosr = fabs( m_dRadius * cos(dangTmp)); XPoint ptc1, ptc2, mpt; mpt = spt + ept; mpt.Scale(0.5); ads_polar(mpt, ads_angle(spt, ept) - PI / 2.0, dcosr, ptc1); ads_polar(mpt, ads_angle(spt, ept) + PI / 2.0, dcosr, ptc2); if (dang > 0) { if (fabs(dang) > PI) { m_ptCenter = ptc1; } else { m_ptCenter = ptc2; } m_dstartAngle = ads_angle(m_ptCenter, spt); m_dendAngle = ads_angle(m_ptCenter, ept); } else { if (fabs(dang) > PI) { m_ptCenter = ptc2; } else { m_ptCenter = ptc1; } m_dstartAngle = ads_angle(m_ptCenter, ept); m_dendAngle = ads_angle(m_ptCenter, spt); } return true; } int XArc::Intersection(const XLine* pLine, ads_point ptRp1, ads_point ptRp2) const { if (pLine == NULL) { return 0; } return pLine->Intersection(this,ptRp1,ptRp2); } int XArc::Intersection(const XArc* pArc, ads_point ptRp1, ads_point ptRp2) const { //zjq 2009-08-31 修改存取方式 if (pArc == NULL) { return 0; } ASSERT(pArc != NULL); if (!IsEqual(1.0E-5, 2, pArc->m_ptCenter.z, m_ptCenter.z)) { return 0; } AcGeCircArc3d cirT(m_ptCenter.AsAcGePoint3d(),AcGeVector3d::kZAxis,m_dRadius); AcGeCircArc3d cirO(pArc->m_ptCenter.AsAcGePoint3d(),AcGeVector3d::kZAxis,pArc->m_dRadius); //同心 if ( m_ptCenter.AsAcGePoint3d().distanceTo(pArc->m_ptCenter.AsAcGePoint3d()) < 1.e-3) { return 0; } int nInt = 0; XPoint pt1,pt2; cirT.intersectWith(cirO,nInt,pt1,pt2); if (nInt == 0) { return 0; } int nt1 = 0, nt2 = 0; nt1 = ((pt1 & (*pArc)) != PR_OUTSIDE) && ((pt1 & (*this)) != PR_OUTSIDE); nt2 = ((pt2 & (*pArc)) != PR_OUTSIDE) && ((pt2 & (*this)) != PR_OUTSIDE); if (ptRp1) { if (nt1) { pt1 > ptRp1; } if (!nt1 && nt2) { pt2 > ptRp1; } } if (ptRp2) { if (nt2 && nt1) { pt2 > ptRp2; } } if (nt2 + nt1 == 2) { if (asPnt3d(ptRp1).distanceTo(asPnt3d(ptRp2)) < _DIST_SNAP) { nt2 = 0; } } return nt1 + nt2; } int XArc::Intersection(const XCircle* pCir,ads_point ptRp1, ads_point ptRp2) const { if (pCir == NULL) { return 0; } return pCir->Intersection(this,ptRp1,ptRp2); } int XArc::HitTest2d(const XPoint &ptTest) const { int nHitFlag = XCircle::HitTest2d(ptTest); if (nHitFlag == 5) { XPoint ptStart, ptEnd; GetStartPoint(ptStart); GetEndPoint(ptEnd); if (ptTest.Distance2d(ptStart) < _DIST_SNAP) { nHitFlag = 3; } else if (ptTest.Distance2d(ptEnd) < _DIST_SNAP) { nHitFlag = 4; } else { //zjq 2009-08-31 修改存取方式 double dSAng = m_dstartAngle; double dEAng = m_dendAngle; XPoint ptCen = m_ptCenter; double dAng = ads_angle(ptCen, ptTest); double dAng1 = CT_std_angle(dAng - dSAng); double dAng2 = CT_std_angle(dEAng - dAng); if ( ( dSAng < dEAng && (dAng < dSAng || dAng > dEAng) ) || (dSAng > dEAng && (dAng > dSAng || dAng < dEAng) )) { if (dAng1 < dAng2) { nHitFlag = 6; } else { nHitFlag = 7; } } } } return nHitFlag; } int XArc::OSnap(int nMode, XPoint &ptPick) const { switch(nMode) { case OS_MID: { MidPoint(ptPick); return nMode; } case OS_END: { XPoint ptStart, ptEnd; GetStartPoint(ptStart); GetEndPoint(ptEnd); ptPick = XLine(ptStart, ptEnd).NearPoint(ptPick); return nMode; } default: return XCircle::OSnap(nMode, ptPick); } return OS_NON; } int XArc::PtOnArc(const XPoint &pt) const { return XPrivate::AT_in_arc((double *)&pt.x,GetCenterPt(), GetRadius(), GetStarAngle(),GetEndAngle()); } int XArc::GetExtend(ads_point lowPt, ads_point upPt) const { double dRad = GetRadius(); if (dRad < _DIST_SNAP) { return XCircle::GetExtend(lowPt, upPt); } XPoint spt, ept,ptCen; double dSAng = GetStarAngle(); double dEAng = GetEndAngle(); ptCen = GetCenterPt(); ads_polar(ptCen, dSAng, dRad, spt); ads_polar(ptCen, dEAng, dRad, ept); ads_real dXm = max(spt.x, ept.x); ads_real dXn = min(spt.x, ept.x); ads_real dYm = max(spt.y, ept.y); ads_real dYn = min(spt.y, ept.y); XPoint p1 = ptCen + XPoint(dRad, 0); XPoint p2 = ptCen + XPoint(0, dRad); XPoint p3 = ptCen + XPoint(-dRad, 0); XPoint p4 = ptCen + XPoint(0, -dRad); int nflg1 = p1 & (*this); int nflg2 = p2 & (*this); if (nflg1 == PR_INSIDE) { dXm = p1.x; } if (nflg2 == PR_INSIDE) { dYm = p2.y; } if ((p3 & (*this)) == PR_INSIDE) { dXn = p3.x; } if ((p4 & (*this)) == PR_INSIDE) { dYn = p4.y; } *(XPoint *)lowPt = XPoint(dXn, dYn, ptCen.z); *(XPoint *)upPt = XPoint(dXm, dYm, ptCen.z); return RTNORM; } /* ads_real XArc::GetLength() const { return Bulge() * GetRadius(); } ads_real XArc::ChordLength() const { return fabs(2.0 * GetRadius() * sin(Bulge() / 2.0)); } void XArc::MidPoint(XPoint &ptres) const { ads_polar(GetCenterPt(), MidAngle(), GetRadius(), ptres); } XPoint XArc::MidPoint() const { XPoint ptres; ads_polar(GetCenterPt(), MidAngle(), GetRadius(), ptres); return ptres; }*/ bool XArc::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); SetCenterPt(cir.center()); SetRadius(cir.radius()); SetStarAngle(ads_angle(GetCenterPt(), ptStart)); SetEndAngle(ads_angle(GetCenterPt(), ptEnd)); return true; } void XArc::SetAngleByPoints(const XPoint &ptStart, const XPoint &ptEnd) { SetStarAngle( ads_angle(GetCenterPt(), ptStart)); SetEndAngle( ads_angle(GetCenterPt(), ptEnd)); } void XArc::GetStartPoint(XPoint &ptStart) const { ads_polar(GetCenterPt(), GetStarAngle(), GetRadius(), ptStart); } void XArc::GetEndPoint(XPoint &ptEnd) const { ads_polar(GetCenterPt(), GetEndAngle(), GetRadius(), ptEnd); } ads_real XArc::Area() const { //zjq 2009-08-31 修改存取方式 return CT_std_angle(m_dendAngle - m_dstartAngle) * m_dRadius * m_dRadius / 2.0; } ads_real XArc::PathArea() const { double dSAng = GetStarAngle(); double dEAng = GetEndAngle(); double dRad = GetRadius(); ads_real dorgArea = (dEAng >= dSAng) ? -(dEAng - sin(2.0 * dEAng) / 2.0 - dSAng + sin(2.0 * dSAng) / 2.0) * 0.5 * dRad * dRad : -( 2 * PI - dSAng + sin(2.0 * dSAng) / 2.0 + dEAng - sin(2.0 * dEAng) / 2.0) * 0.5 * dRad * dRad; ads_real daddArea = m_ptCenter.y * dRad * (cos(dEAng) - cos(dSAng)); return dorgArea + daddArea; } ads_real XArc::IDirection(int pt) const { //zjq 2009-08-31 修改存取方式 return (pt ? CT_std_angle(m_dendAngle - PI / 2.0) : CT_std_angle(m_dstartAngle + PI / 2.0)); } ads_real XArc::ODirection(int pt) const { return CT_RevDrt(IDirection(pt)); } /* XArc XArc::Offset(ads_real dist) const { ads_real r = GetRadius() + dist; if (r < _DIST_SNAP) { r = 0; } return XArc(GetCenterPt(), r, GetStarAngle(), GetEndAngle()); } */ int XArc::Modify(const Entity* pEnt) const { ASSERT(pEnt != NULL); Entity refEnt = *pEnt; XPoint ptCen = GetCenterPt(); refEnt.SetData(10, &(ptCen.x)); refEnt.SetData(50, GetStarAngle()); refEnt.SetData(51, GetEndAngle()); refEnt.SetData(40, GetRadius()); return refEnt.Modify(); } int XArc::MakeEntity(const Entity* pEnt) const { ASSERT(pEnt != NULL); Entity entTmp = *pEnt; Groups g(_T("*")); RBList ebuf = ads_entgetx(entTmp, (resbuf *)&g); //2013-04-21 2013移植 // ebuf.SetData(10, &(GetCenterPt().x)); ads_real dbX = GetCenterPt().x; ebuf.SetData(10, &dbX); ebuf.SetData(50, GetStarAngle()); ebuf.SetData(51, GetEndAngle()); ebuf.SetData(40, GetRadius()); return ads_entmake(ebuf); } ads_real* XArc::SelectNear(ads_point pt1, ads_point pt2) const { XPoint spt, ept,ptCen; ptCen = GetCenterPt(); double dSAng = GetStarAngle(); double dEAng = GetEndAngle(); double dRad = GetRadius(); ads_polar(ptCen, dSAng, dRad, spt); ads_polar(ptCen, dEAng, dRad, ept); ads_real dis1 = min(ads_distance(pt1, spt), ads_distance(pt1, ept)); ads_real dis2 = min(ads_distance(pt2, spt), ads_distance(pt2, ept)); return (dis1 < dis2) ? pt1 : pt2; } int XArc::Make(const TCHAR *szlay) const { TCHAR szlayer[80] = _T(""); if (szlay) { _tcscpy(szlayer, szlay); } else { xg_getvar(_T("clayer"), szlayer); } double dSAng = GetStarAngle(); double dEAng = GetEndAngle(); double dRad = GetRadius(); XPoint ptCen = GetCenterPt(); return XExport::MakeEntity(RTDXF0, _T("ARC"), 8, szlayer, 10, &(ptCen.x), 40, dRad, 50, dSAng, 51, dEAng, NULL); } int XArc::GetSubArc(const XPoint &ptloc, ads_real dchordLen, XArc &arcRes) const { if (XCircle::GetSubArc(ptloc, dchordLen, arcRes) != RTNORM) { return RTERROR; } //zjq 2009-08-31 修改存取方式 int nflg1 = AngleFlag(arcRes.m_dstartAngle), nflg2 = AngleFlag(arcRes.m_dendAngle); if (nflg1 != PR_OUTSIDE && nflg2 != PR_OUTSIDE) { return RTNORM; } return RTERROR; } void XArc::TransUCS(ads_matrix mat) { XPoint ptStart, ptEnd, ptMid; GetStartPoint(ptStart); GetEndPoint(ptEnd); MidPoint(ptMid); ptStart.TransformBy(mat); ptEnd.TransformBy(mat); ptMid.TransformBy(mat); *this = XArc(ptStart, ptMid, ptEnd); } bool XArc::IsKindOf(XEntity::TEntityId entType) const { switch(entType) { case XEntity::eEntity: case XEntity::eCurve: case XEntity::eCircle: case XEntity::eArc: return true; } return false; } XEntity::TEntityId XArc::Type() const { return XEntity::eArc; } void XArc::CopyFrom(const XEntity* pSrc) { if (pSrc->IsKindOf(XEntity::eArc)) { //zjq 2009-08-31 修改存取方式 XArc* pArc = (XArc*)pSrc; m_dstartAngle = pArc->m_dstartAngle; m_dendAngle = pArc->m_dendAngle; m_ptCenter = pArc->m_ptCenter; m_dRadius = pArc->m_dRadius; //zjq 2009-08-31 修改存取方式 /* SetStarAngle(pArc->GetStarAngle()); SetEndAngle(pArc->GetEndAngle()); SetCenterPt(pArc->GetCenterPt()); SetRadius(pArc->GetRadius()); */ } else if(pSrc->IsKindOf(XEntity::eCircle)) { XCircle* pArc = (XCircle*)pSrc; m_dstartAngle = 0.0; m_dendAngle = 2.0 * PI; m_dRadius = pArc->m_dRadius; m_ptCenter = pArc->m_ptCenter; //zjq 2009-08-31 修改存取方式 /* SetStarAngle(0.0); SetEndAngle(2.0 * PI); SetRadius(pArc->GetRadius()); SetCenterPt(pArc->GetCenterPt()); */ } }