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

606 lines
12 KiB
C++

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