#include "StdAfx.h" #include "globalFunc.h" #include "GeArc.h" #include "GeLine.h" #include "EntitySet.h" #include "GeCurveInline.h" GeArc::GeArc() { } GeArc::GeArc(const GeArc &src) : GeCircle(src), GeSector(src) { } GeArc::GeArc(const EntitySet &aCircle) : GeCircle(aCircle), GeSector(aCircle) { } GeArc::GeArc(ads_point ptcenter, double dradius, double ptstartAngle, double ptendAngle) :GeCircle(ptcenter,dradius) { m_dstartAngle = ptstartAngle; m_dendAngle = ptendAngle; } GeArc::GeArc(const ADSGePoint3d &spt, const ADSGePoint3d &ept, ads_real dang) { Set(spt,ept,dang); } GeArc::GeArc(const EntitySet &xarc, ads_matrix mat) : GeCircle(xarc), GeSector(xarc) { if (mat) { //lfy 2010-08-31 修改存取方式 ADSGePoint3d 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); } } GeArc::GeArc(const ADSGePoint3d &startPoint, const ADSGePoint3d &pt2, const ADSGePoint3d &endPoint) :GeCircle(startPoint, pt2, endPoint) { GeCircle &cir = *this; if(!cir) { return; } //Set(startPoint, pt2, endPoint); SetAngleByPoints(startPoint, endPoint); if ((pt2 & (*this)) != PR_INSIDE) { //Set(endPoint, pt2, startPoint); SetAngleByPoints(endPoint, startPoint); } } GeArc::~GeArc() { } bool GeArc::Set(const ADSGePoint3d &spt, const ADSGePoint3d &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)); ADSGePoint3d 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 GeArc::Intersection(const GeLine* pLine, ads_point ptRp1, ads_point ptRp2) const { if (pLine == NULL) { return 0; } return pLine->Intersection(this,ptRp1,ptRp2); } int GeArc::Intersection(const GeArc* pArc, ads_point ptRp1, ads_point ptRp2) const { //lfy 2010-08-31 修改存取方式 if (pArc == NULL) { return 0; } ASSERT(pArc != NULL); if (!GlobalFunc::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; ADSGePoint3d 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)) < g_Option::instance()._DIST_SNAP) { nt2 = 0; } } return nt1 + nt2; } int GeArc::Intersection(const GeCircle* pCir,ads_point ptRp1, ads_point ptRp2) const { if (pCir == NULL) { return 0; } return pCir->Intersection(this,ptRp1,ptRp2); } int GeArc::HitTest2d(const ADSGePoint3d &ptTest) const { int nHitFlag = GeCircle::HitTest2d(ptTest); if (nHitFlag == 5) { ADSGePoint3d ptStart, ptEnd; GetStartPoint(ptStart); GetEndPoint(ptEnd); if (ptTest.Distance2d(ptStart) < g_Option::instance()._DIST_SNAP) { nHitFlag = 3; } else if (ptTest.Distance2d(ptEnd) < g_Option::instance()._DIST_SNAP) { nHitFlag = 4; } else { //lfy 2010-08-31 修改存取方式 double dSAng = m_dstartAngle; double dEAng = m_dendAngle; ADSGePoint3d ptCen = m_ptCenter; double dAng = ads_angle(ptCen, ptTest); double dAng1 = GlobalFunc::AngleRangeTo2PI(dAng - dSAng); double dAng2 = GlobalFunc::AngleRangeTo2PI(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 GeArc::OSnap(int nMode, ADSGePoint3d &ptPick) const { switch(nMode) { case OS_MID: { MidPoint(ptPick); return nMode; } case OS_END: { ADSGePoint3d ptStart, ptEnd; GetStartPoint(ptStart); GetEndPoint(ptEnd); ptPick = GeLine(ptStart, ptEnd).NearPoint(ptPick); return nMode; } default: return GeCircle::OSnap(nMode, ptPick); } return OS_NON; } int GeArc::PtOnArc(const ADSGePoint3d &pt) const { return GlobalFunc::GetPointInArcType((double *)&pt.x,GetCenterPt(), GetRadius(), GetStarAngle(),GetEndAngle()); } int GeArc::GetExtend(ads_point lowPt, ads_point upPt) const { double dRad = GetRadius(); if (dRad < g_Option::instance()._DIST_SNAP) { return GeCircle::GetExtend(lowPt, upPt); } ADSGePoint3d 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); ADSGePoint3d p1 = ptCen + ADSGePoint3d(dRad, 0); ADSGePoint3d p2 = ptCen + ADSGePoint3d(0, dRad); ADSGePoint3d p3 = ptCen + ADSGePoint3d(-dRad, 0); ADSGePoint3d p4 = ptCen + ADSGePoint3d(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; } *(ADSGePoint3d *)lowPt = ADSGePoint3d(dXn, dYn, ptCen.z); *(ADSGePoint3d *)upPt = ADSGePoint3d(dXm, dYm, ptCen.z); return RTNORM; } /* ads_real GeArc::GetLength() const { return Bulge() * GetRadius(); } ads_real GeArc::ChordLength() const { return fabs(2.0 * GetRadius() * sin(Bulge() / 2.0)); } void GeArc::MidPoint(ADSGePoint3d &ptres) const { ads_polar(GetCenterPt(), MidAngle(), GetRadius(), ptres); } ADSGePoint3d GeArc::MidPoint() const { ADSGePoint3d ptres; ads_polar(GetCenterPt(), MidAngle(), GetRadius(), ptres); return ptres; }*/ bool GeArc::Set(const ADSGePoint3d &ptStart, const ADSGePoint3d &ptOn, const ADSGePoint3d &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 GeArc::SetAngleByPoints(const ADSGePoint3d &ptStart, const ADSGePoint3d &ptEnd) { SetStarAngle( ads_angle(GetCenterPt(), ptStart)); SetEndAngle( ads_angle(GetCenterPt(), ptEnd)); } void GeArc::GetStartPoint(ADSGePoint3d &ptStart) const { ads_polar(GetCenterPt(), GetStarAngle(), GetRadius(), ptStart); } void GeArc::GetEndPoint(ADSGePoint3d &ptEnd) const { ads_polar(GetCenterPt(), GetEndAngle(), GetRadius(), ptEnd); } ads_real GeArc::Area() const { //lfy 2010-08-31 修改存取方式 return GlobalFunc::AngleRangeTo2PI(m_dendAngle - m_dstartAngle) * m_dRadius * m_dRadius / 2.0; } ads_real GeArc::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 GeArc::IDirection(int pt) const { //lfy 2010-08-31 修改存取方式 return (pt ? GlobalFunc::AngleRangeTo2PI(m_dendAngle - PI / 2.0) : GlobalFunc::AngleRangeTo2PI(m_dstartAngle + PI / 2.0)); } ads_real GeArc::ODirection(int pt) const { return RevDrtAngle(IDirection(pt)); } /* GeArc GeArc::Offset(ads_real dist) const { ads_real r = GetRadius() + dist; if (r < g_Option::instance()._DIST_SNAP) { r = 0; } return GeArc(GetCenterPt(), r, GetStarAngle(), GetEndAngle()); } */ int GeArc::Modify(const EntitySet* pEnt) const { ASSERT(pEnt != NULL); EntitySet refEnt = *pEnt; ADSGePoint3d ptCen = GetCenterPt(); refEnt.SetData(10, &(ptCen.x)); refEnt.SetData(50, GetStarAngle()); refEnt.SetData(51, GetEndAngle()); refEnt.SetData(40, GetRadius()); return refEnt.Modify(); } int GeArc::MakeEntity(const EntitySet* pEnt) const { ASSERT(pEnt != NULL); EntitySet entTmp = *pEnt; RBGroups g(_T("*")); RBList ebuf = ads_entgetx(entTmp, (resbuf *)&g); ADSGePoint3d ptCen = GetCenterPt(); ebuf.SetData(10, &(ptCen.x)); ebuf.SetData(50, GetStarAngle()); ebuf.SetData(51, GetEndAngle()); ebuf.SetData(40, GetRadius()); return ads_entmake(ebuf); } ads_real* GeArc::SelectNear(ads_point pt1, ads_point pt2) const { ADSGePoint3d 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 GeArc::Make(const TCHAR *szlay) const { TCHAR szlayer[80] = _T(""); if (szlay) { _tcscpy(szlayer, szlay); } else { GlobalFunc::TGGetVar(_T("clayer"), szlayer); } double dSAng = GetStarAngle(); double dEAng = GetEndAngle(); double dRad = GetRadius(); ADSGePoint3d ptCen = GetCenterPt(); return GlobalFunc::MakeEntity(RTDXF0, _T("ARC"), 8, szlayer, 10, &(ptCen.x), 40, dRad, 50, dSAng, 51, dEAng, NULL); } int GeArc::GetSubArc(const ADSGePoint3d &ptloc, ads_real dchordLen, GeArc &arcRes) const { if (GeCircle::GetSubArc(ptloc, dchordLen, arcRes) != RTNORM) { return RTERROR; } //lfy 2010-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 GeArc::TransUCS(ads_matrix mat) { ADSGePoint3d ptStart, ptEnd, ptMid; GetStartPoint(ptStart); GetEndPoint(ptEnd); MidPoint(ptMid); ptStart.TransformBy(mat); ptEnd.TransformBy(mat); ptMid.TransformBy(mat); *this = GeArc(ptStart, ptMid, ptEnd); } bool GeArc::IsKindOf(GeEntity::TEntityId entType) const { switch(entType) { case GeEntity::eEntity: case GeEntity::eCurve: case GeEntity::eCircle: case GeEntity::eArc: return true; } return false; } GeEntity::TEntityId GeArc::Type() const { return GeEntity::eArc; } void GeArc::CopyFrom(const GeEntity* pSrc) { if (pSrc->IsKindOf(GeEntity::eArc)) { //lfy 2010-08-31 修改存取方式 GeArc* pArc = (GeArc*)pSrc; m_dstartAngle = pArc->m_dstartAngle; m_dendAngle = pArc->m_dendAngle; m_ptCenter = pArc->m_ptCenter; m_dRadius = pArc->m_dRadius; //lfy 2010-08-31 修改存取方式 /* SetStarAngle(pArc->GetStarAngle()); SetEndAngle(pArc->GetEndAngle()); SetCenterPt(pArc->GetCenterPt()); SetRadius(pArc->GetRadius()); */ } else if(pSrc->IsKindOf(GeEntity::eCircle)) { GeCircle* pArc = (GeCircle*)pSrc; m_dstartAngle = 0.0; m_dendAngle = 2.0 * PI; m_dRadius = pArc->m_dRadius; m_ptCenter = pArc->m_ptCenter; //lfy 2010-08-31 修改存取方式 /* SetStarAngle(0.0); SetEndAngle(2.0 * PI); SetRadius(pArc->GetRadius()); SetCenterPt(pArc->GetCenterPt()); */ } } GeArc& GeArc::operator = (const GeSector &src) { m_dstartAngle = src.m_dstartAngle; m_dendAngle = src.m_dendAngle; return *this; } GeArc& GeArc::operator = (const GeArc &src) { if (this != &src) { m_dstartAngle = src.m_dstartAngle; m_dendAngle = src.m_dendAngle; m_ptCenter = src.m_ptCenter; m_dRadius = src.m_dRadius; } return *this; } int GeArc::operator ! () const { return (GeCircle::operator !() || GetLength() < g_Option::instance()._DIST_SNAP); } bool GeArc::operator == (const GeArc &src) const { return (GeCircle::operator == (src) && GeSector::operator == (src)); } GeArc GeArc::Offset(ads_real dist) const { ads_real r = m_dRadius + dist; if (r < g_Option::instance()._DIST_SNAP) { r = 0; } return GeArc(m_ptCenter, r, m_dstartAngle, m_dendAngle); } ads_real GeArc::GetLength() const { return Bulge() * m_dRadius; } ads_real GeArc::ChordLength() const { return fabs(2.0 * m_dRadius * sin(Bulge() / 2.0)); } void GeArc::MidPoint(ADSGePoint3d &ptres) const { ads_polar(m_ptCenter, MidAngle(), m_dRadius, ptres); } ADSGePoint3d GeArc::MidPoint() const { ADSGePoint3d ptres; ads_polar(m_ptCenter, MidAngle(), m_dRadius, ptres); return ptres; }