//-----------------------------------------------------------------------------+ // Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd. // = FileName : TGGeArc 弧类 // = Version : ver2.0 // = Author : wlw // = CreateDate : 2002-09-09 // = Description: TGGeArc 类定义 // = Maintainers: // //-----------------------------------------------------------------------------+ #include "StdAfx.h" #include "TGGeArc.h" #include "TGGeLine.h" #include "TEntitySet.h" #include "TchGlobalFunc.h" #include "TchPrivateGlobalFunc.h" #include "TchGlobalCurveFunc.h" #include "TGGeCurveInline.h" TGGeArc::TGGeArc() { } TGGeArc::TGGeArc(const TGGeArc &src) : TGGeCircle(src), TGGeSector(src) { } TGGeArc::TGGeArc(const TEntitySet &aCircle) : TGGeCircle(aCircle), TGGeSector(aCircle) { } TGGeArc::TGGeArc(ads_point ptcenter, double dradius, double ptstartAngle, double ptendAngle) :TGGeCircle(ptcenter,dradius) { m_dstartAngle = ptstartAngle; m_dendAngle = ptendAngle; } TGGeArc::TGGeArc(const TADSGePoint3d &spt, const TADSGePoint3d &ept, ads_real dang) { Set(spt,ept,dang); } TGGeArc::TGGeArc(const TEntitySet &xarc, ads_matrix mat) : TGGeCircle(xarc), TGGeSector(xarc) { if (mat) { //lfy 2010-08-31 修改存取方式 TADSGePoint3d 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); } } TGGeArc::TGGeArc(const TADSGePoint3d &startPoint, const TADSGePoint3d &pt2, const TADSGePoint3d &endPoint) :TGGeCircle(startPoint, pt2, endPoint) { TGGeCircle &cir = *this; if(!cir) { return; } //Set(startPoint, pt2, endPoint); SetAngleByPoints(startPoint, endPoint); if ((pt2 & (*this)) != PR_INSIDE) { //Set(endPoint, pt2, startPoint); SetAngleByPoints(endPoint, startPoint); } } TGGeArc::~TGGeArc() { } bool TGGeArc::Set(const TADSGePoint3d &spt, const TADSGePoint3d &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)); TADSGePoint3d 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 TGGeArc::Intersection(const TGGeLine* pLine, ads_point ptRp1, ads_point ptRp2) const { if (pLine == NULL) { return 0; } return pLine->Intersection(this,ptRp1,ptRp2); } int TGGeArc::Intersection(const TGGeArc* pArc, ads_point ptRp1, ads_point ptRp2) const { //lfy 2010-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; TADSGePoint3d 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 TGGeArc::Intersection(const TGGeCircle* pCir,ads_point ptRp1, ads_point ptRp2) const { if (pCir == NULL) { return 0; } return pCir->Intersection(this,ptRp1,ptRp2); } int TGGeArc::HitTest2d(const TADSGePoint3d &ptTest) const { int nHitFlag = TGGeCircle::HitTest2d(ptTest); if (nHitFlag == 5) { TADSGePoint3d ptStart, ptEnd; GetStartPoint(ptStart); GetEndPoint(ptEnd); if (ptTest.Distance2d(ptStart) < _DIST_SNAP) { nHitFlag = 3; } else if (ptTest.Distance2d(ptEnd) < _DIST_SNAP) { nHitFlag = 4; } else { //lfy 2010-08-31 修改存取方式 double dSAng = m_dstartAngle; double dEAng = m_dendAngle; TADSGePoint3d ptCen = m_ptCenter; double dAng = ads_angle(ptCen, ptTest); double dAng1 = AngleRangeTo2PI(dAng - dSAng); double dAng2 = 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 TGGeArc::OSnap(int nMode, TADSGePoint3d &ptPick) const { switch(nMode) { case OS_MID: { MidPoint(ptPick); return nMode; } case OS_END: { TADSGePoint3d ptStart, ptEnd; GetStartPoint(ptStart); GetEndPoint(ptEnd); ptPick = TGGeLine(ptStart, ptEnd).NearPoint(ptPick); return nMode; } default: return TGGeCircle::OSnap(nMode, ptPick); } return OS_NON; } int TGGeArc::PtOnArc(const TADSGePoint3d &pt) const { return TchPrivate::GetPointInArcType((double *)&pt.x,GetCenterPt(), GetRadius(), GetStarAngle(),GetEndAngle()); } int TGGeArc::GetExtend(ads_point lowPt, ads_point upPt) const { double dRad = GetRadius(); if (dRad < _DIST_SNAP) { return TGGeCircle::GetExtend(lowPt, upPt); } TADSGePoint3d 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); TADSGePoint3d p1 = ptCen + TADSGePoint3d(dRad, 0); TADSGePoint3d p2 = ptCen + TADSGePoint3d(0, dRad); TADSGePoint3d p3 = ptCen + TADSGePoint3d(-dRad, 0); TADSGePoint3d p4 = ptCen + TADSGePoint3d(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; } *(TADSGePoint3d *)lowPt = TADSGePoint3d(dXn, dYn, ptCen.z); *(TADSGePoint3d *)upPt = TADSGePoint3d(dXm, dYm, ptCen.z); return RTNORM; } /* ads_real TGGeArc::GetLength() const { return Bulge() * GetRadius(); } ads_real TGGeArc::ChordLength() const { return fabs(2.0 * GetRadius() * sin(Bulge() / 2.0)); } void TGGeArc::MidPoint(TADSGePoint3d &ptres) const { ads_polar(GetCenterPt(), MidAngle(), GetRadius(), ptres); } TADSGePoint3d TGGeArc::MidPoint() const { TADSGePoint3d ptres; ads_polar(GetCenterPt(), MidAngle(), GetRadius(), ptres); return ptres; }*/ bool TGGeArc::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); SetCenterPt(cir.center()); SetRadius(cir.radius()); SetStarAngle(ads_angle(GetCenterPt(), ptStart)); SetEndAngle(ads_angle(GetCenterPt(), ptEnd)); return true; } void TGGeArc::SetAngleByPoints(const TADSGePoint3d &ptStart, const TADSGePoint3d &ptEnd) { SetStarAngle( ads_angle(GetCenterPt(), ptStart)); SetEndAngle( ads_angle(GetCenterPt(), ptEnd)); } void TGGeArc::GetStartPoint(TADSGePoint3d &ptStart) const { ads_polar(GetCenterPt(), GetStarAngle(), GetRadius(), ptStart); } void TGGeArc::GetEndPoint(TADSGePoint3d &ptEnd) const { ads_polar(GetCenterPt(), GetEndAngle(), GetRadius(), ptEnd); } ads_real TGGeArc::Area() const { //lfy 2010-08-31 修改存取方式 return AngleRangeTo2PI(m_dendAngle - m_dstartAngle) * m_dRadius * m_dRadius / 2.0; } ads_real TGGeArc::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 TGGeArc::IDirection(int pt) const { //lfy 2010-08-31 修改存取方式 return (pt ? AngleRangeTo2PI(m_dendAngle - PI / 2.0) : AngleRangeTo2PI(m_dstartAngle + PI / 2.0)); } ads_real TGGeArc::ODirection(int pt) const { return RevDrtAngle(IDirection(pt)); } /* TGGeArc TGGeArc::Offset(ads_real dist) const { ads_real r = GetRadius() + dist; if (r < _DIST_SNAP) { r = 0; } return TGGeArc(GetCenterPt(), r, GetStarAngle(), GetEndAngle()); } */ int TGGeArc::Modify(const TEntitySet* pEnt) const { ASSERT(pEnt != NULL); TEntitySet refEnt = *pEnt; TADSGePoint3d ptCen = GetCenterPt(); refEnt.SetData(10, &(ptCen.x)); refEnt.SetData(50, GetStarAngle()); refEnt.SetData(51, GetEndAngle()); refEnt.SetData(40, GetRadius()); return refEnt.Modify(); } int TGGeArc::MakeEntity(const TEntitySet* pEnt) const { ASSERT(pEnt != NULL); TEntitySet entTmp = *pEnt; TGroups g(_T("*")); TRBList ebuf = ads_entgetx(entTmp, (resbuf *)&g); TADSGePoint3d 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* TGGeArc::SelectNear(ads_point pt1, ads_point pt2) const { TADSGePoint3d 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 TGGeArc::Make(const TCHAR *szlay) const { TCHAR szlayer[80] = _T(""); if (szlay) { _tcscpy(szlayer, szlay); } else { TGGetVar(_T("clayer"), szlayer); } double dSAng = GetStarAngle(); double dEAng = GetEndAngle(); double dRad = GetRadius(); TADSGePoint3d ptCen = GetCenterPt(); return TchExport::MakeEntity(RTDXF0, _T("ARC"), 8, szlayer, 10, &(ptCen.x), 40, dRad, 50, dSAng, 51, dEAng, NULL); } int TGGeArc::GetSubArc(const TADSGePoint3d &ptloc, ads_real dchordLen, TGGeArc &arcRes) const { if (TGGeCircle::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 TGGeArc::TransUCS(ads_matrix mat) { TADSGePoint3d ptStart, ptEnd, ptMid; GetStartPoint(ptStart); GetEndPoint(ptEnd); MidPoint(ptMid); ptStart.TransformBy(mat); ptEnd.TransformBy(mat); ptMid.TransformBy(mat); *this = TGGeArc(ptStart, ptMid, ptEnd); } bool TGGeArc::IsKindOf(TGGeEntity::TEntityId entType) const { switch(entType) { case TGGeEntity::eEntity: case TGGeEntity::eCurve: case TGGeEntity::eCircle: case TGGeEntity::eArc: return true; } return false; } TGGeEntity::TEntityId TGGeArc::Type() const { return TGGeEntity::eArc; } void TGGeArc::CopyFrom(const TGGeEntity* pSrc) { if (pSrc->IsKindOf(TGGeEntity::eArc)) { //lfy 2010-08-31 修改存取方式 TGGeArc* pArc = (TGGeArc*)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(TGGeEntity::eCircle)) { TGGeCircle* pArc = (TGGeCircle*)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()); */ } }