Files
envi-code/SourceCode/Code2026/tg_shs/shs_geLib/TGGeArc.cpp
T
2026-09-28 15:28:50 +08:00

602 lines
13 KiB
C++

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