602 lines
13 KiB
C++
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());
|
|
*/
|
|
}
|
|
}
|