Files
envi-code/SourceCode/Code2026/Dimension/GeArc.cpp
T
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

653 lines
13 KiB
C++

#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;
}