257 lines
4.9 KiB
C++
257 lines
4.9 KiB
C++
//-----------------------------------------------------------------------------+
|
|
// Copyright (C), 1998-2007, SH Software Co. Ltd.
|
|
// = FileName : XDirectionCurve 类
|
|
// = Version : ver2.0
|
|
// = Author : zjq
|
|
// = CreateDate : 2002-09-09
|
|
// = Description: XDirectionCurve 类定义
|
|
// = Maintainers:
|
|
//
|
|
//-----------------------------------------------------------------------------+
|
|
#include "StdAfx.h"
|
|
#include "XDirectionCurve.h"
|
|
#include "XGlobalFunc.h"
|
|
#include "XPrivateGlobalFunc.h"
|
|
|
|
static BOOL IsMirrorTransform(const resbuf *rb1, const resbuf *rb2)
|
|
{
|
|
XPoint ptOrg, ptX(1000, 0), ptY(0, 1000), ptOrg1, ptX1, ptY1;
|
|
|
|
ads_trans(ptOrg, rb1, rb2, FALSE, ptOrg1);
|
|
ads_trans(ptX, rb1, rb2, FALSE, ptX1);
|
|
ads_trans(ptY, rb1, rb2, FALSE, ptY1);
|
|
|
|
double nAng = CT_std_angle(ads_angle(ptOrg1, ptY1) - ads_angle(ptOrg1, ptX1));
|
|
|
|
return (fabs(nAng - PI * 1.5) < _angSnap);
|
|
}
|
|
|
|
XDirectionCurve::XDirectionCurve(const XPoint &spt, const XPoint &ept, ads_real dAng, int flg)
|
|
: XCurveSegment(spt,ept,dAng, flg)
|
|
{
|
|
|
|
}
|
|
|
|
XDirectionCurve::XDirectionCurve(int flg)
|
|
: XCurveSegment(flg)
|
|
{
|
|
|
|
}
|
|
|
|
XDirectionCurve::XDirectionCurve(const XDirectionCurve &src)
|
|
: XCurveSegment(src)
|
|
{
|
|
|
|
}
|
|
|
|
XDirectionCurve::XDirectionCurve(const XArc &ar, int bMinus)
|
|
{
|
|
XCurveSegment &seg = *this;
|
|
seg = ar;
|
|
|
|
if (bMinus)
|
|
{
|
|
m_dBulge = -fabs(m_dBulge);
|
|
XPrivate::Exchange(m_startPoint, m_endPoint);
|
|
}
|
|
}
|
|
|
|
XDirectionCurve::~XDirectionCurve()
|
|
{
|
|
|
|
}
|
|
|
|
XArc XDirectionCurve::GetArc() const
|
|
{
|
|
if (IsMinusArc())
|
|
{
|
|
return XArc(m_endPoint, m_startPoint, fabs(m_dBulge));
|
|
}
|
|
|
|
return XArc(m_startPoint, m_endPoint, m_dBulge);
|
|
}
|
|
|
|
int XDirectionCurve::IsMinusArc() const
|
|
{
|
|
return m_dBulge < -1.0E-8;
|
|
}
|
|
|
|
XCurveSegment XDirectionCurve::GetCurve() const
|
|
{
|
|
XCurveSegment seg;
|
|
if (IsMinusArc())
|
|
{
|
|
seg = GetArc();
|
|
}
|
|
else
|
|
{
|
|
seg = *this;
|
|
}
|
|
|
|
return seg;
|
|
}
|
|
|
|
void XDirectionCurve::TransUCS(const resbuf *rb1, const resbuf *rb2)
|
|
{
|
|
XLine::TransUCS(rb2, rb2);
|
|
if (IsMirrorTransform(rb1, rb2))
|
|
{
|
|
m_dBulge = -m_dBulge;
|
|
}
|
|
}
|
|
|
|
void XDirectionCurve::TransUCS(ads_matrix mat)
|
|
{
|
|
XLine::TransformBy(mat);
|
|
if (IsMirrorMatrix(mat))
|
|
{
|
|
m_dBulge = -m_dBulge;
|
|
}
|
|
}
|
|
|
|
void XDirectionCurve::Reverse()
|
|
{
|
|
XPrivate::Exchange(m_startPoint, m_endPoint);
|
|
m_dBulge = -m_dBulge;
|
|
}
|
|
|
|
// dist: <0 left side; >0 right siede
|
|
XDirectionCurve XDirectionCurve::Offset(ads_real dist, int flg) const
|
|
{
|
|
assert(!Is(CURVE_CIRCLE));
|
|
|
|
XPoint spt, ept;
|
|
if (Is(CURVE_LINE))
|
|
{
|
|
ads_real ang = XLine::Direction()-PI/2.0;
|
|
ads_polar(m_startPoint, ang, dist, spt);
|
|
ads_polar(m_endPoint, ang, dist, ept);
|
|
|
|
return XDirectionCurve(spt, ept, 0.0, flg);
|
|
}
|
|
|
|
XArc aArc = GetArc();
|
|
ads_real r = (!IsMinusArc()) ? (aArc.GetRadius() + dist) : (aArc.GetRadius() - dist);
|
|
|
|
if (r < _DIST_SNAP)
|
|
{
|
|
return XDirectionCurve();
|
|
}
|
|
|
|
aArc.SetRadius(r);
|
|
|
|
XDirectionCurve curve(aArc, IsMinusArc());
|
|
curve.m_nFlag = flg;
|
|
return curve;
|
|
}
|
|
|
|
ads_real XDirectionCurve::IDirection(int npt) const
|
|
{
|
|
if (IsMinusArc())
|
|
{
|
|
return GetCurve().IDirection(1 - npt);
|
|
}
|
|
|
|
return XCurveSegment::IDirection(npt);
|
|
}
|
|
|
|
int XDirectionCurve::OnWhichSide(const XPoint &src) const
|
|
{
|
|
int nSide = GetCurve().OnWhichSide(src);
|
|
if (IsMinusArc())
|
|
{
|
|
nSide = 1 - nSide;
|
|
}
|
|
|
|
return nSide;
|
|
}
|
|
|
|
int XDirectionCurve::OnWhichSide1(const XPoint &src) const
|
|
{
|
|
int nSide = GetCurve().OnWhichSide1(src);
|
|
if (IsMinusArc())
|
|
{
|
|
nSide = 1 - nSide;
|
|
}
|
|
|
|
return nSide;
|
|
}
|
|
|
|
ads_real XDirectionCurve::PathArea(XPoint &tmpt) const
|
|
{
|
|
double nRet = GetCurve().PathArea(tmpt);
|
|
if (IsMinusArc())
|
|
{
|
|
nRet = -nRet;
|
|
}
|
|
|
|
return nRet;
|
|
}
|
|
|
|
ads_real XDirectionCurve::Direction(const XPoint &pt) const
|
|
{
|
|
double nRet = GetCurve().Direction(pt);
|
|
if (IsMinusArc())
|
|
{
|
|
nRet = -nRet;
|
|
}
|
|
|
|
return nRet;
|
|
}
|
|
|
|
void XDirectionCurve::AsPoly2D(XPoly2D &poly) const
|
|
{
|
|
GetCurve().AsPoly2D(poly);
|
|
if (IsMinusArc())
|
|
{
|
|
poly.Reverse();
|
|
}
|
|
}
|
|
|
|
// 从端点开始沿曲线走过给定距离的点向量
|
|
int XDirectionCurve::Polar(ads_real dDist, XPointDir2d &res, BOOL bFromStart) const
|
|
{
|
|
return GetCurve().Polar(dDist, res, IsMinusArc() ? (!bFromStart) : bFromStart);
|
|
}
|
|
|
|
// 求到端点的沿曲线线位移, 在线内距离为正,否则为负, 和Polar配合使用
|
|
// pt如果不在线上的话则先投影
|
|
ads_real XDirectionCurve::PathDistance(const XPoint &pt, BOOL bFromStart) const
|
|
{
|
|
return GetCurve().PathDistance(pt, IsMinusArc() ? (!bFromStart) : bFromStart);
|
|
}
|
|
|
|
// 求通过pt点的法向
|
|
ads_real XDirectionCurve::OrthoDirection(const XPoint &pt) const
|
|
{
|
|
double nRet = GetCurve().OrthoDirection(pt);
|
|
if (IsMinusArc())
|
|
{
|
|
nRet = CT_std_angle(nRet + PI);
|
|
}
|
|
|
|
return nRet;
|
|
}
|
|
|
|
void XDirectionCurve::SetPoints(const XPoint &ptStart, const XPoint &ptEnd)
|
|
{
|
|
if (IsMinusArc())
|
|
{
|
|
XCurveSegment seg = GetCurve();
|
|
seg.SetPoints(ptEnd, ptStart);
|
|
m_startPoint = seg.GetEndPoint();
|
|
m_endPoint = seg.GetStartPoint();
|
|
m_dBulge = -seg.GetBulge();
|
|
}
|
|
else
|
|
{
|
|
XCurveSegment::SetPoints(ptStart, ptEnd);
|
|
}
|
|
}
|
|
|
|
bool XDirectionCurve::IsDirectionCurve()
|
|
{
|
|
return true;
|
|
}
|
|
|