817 lines
18 KiB
C++
817 lines
18 KiB
C++
#include "stdafx.h"
|
|
|
|
|
|
#define ACCURACY 0.000001
|
|
|
|
XContour::XContour()
|
|
:m_nVertexNum(90)
|
|
{
|
|
}
|
|
|
|
XContour::XContour(const XPoly2D& polySrc,int nVertexNum)
|
|
{
|
|
Init(polySrc,nVertexNum);
|
|
}
|
|
|
|
XContour::XContour(const XContour& src)
|
|
{
|
|
m_nVertexNum = src.m_nVertexNum;
|
|
int nCount = src.Length();
|
|
for (int i = 0; i < nCount; i++) {
|
|
Append(new XPoint(src[i]));
|
|
}
|
|
}
|
|
|
|
XContour::~XContour()
|
|
{
|
|
}
|
|
|
|
|
|
void XContour::Init(const XPoly2D& polySrc,int nVertexNum)
|
|
{
|
|
if (polySrc.Length()<=0)
|
|
return ;
|
|
if (Length()>0)
|
|
Reset();
|
|
m_nVertexNum = nVertexNum;
|
|
assert(m_nVertexNum >= 3);
|
|
double dElev = polySrc[0].z;
|
|
XPoly2D poly = polySrc;
|
|
poly.SetElevation(dElev);
|
|
|
|
Poly2DToVertexs(poly);
|
|
m_ptWeightCenter = ::GetWeightCenter(poly);
|
|
Divide();
|
|
}
|
|
|
|
// 遇弧线离散化
|
|
void XContour::Poly2DToVertexs(const XPoly2D& poly)
|
|
{
|
|
extern int GetCirDivNum(double r, double h);
|
|
extern double g_nCirDeviation;
|
|
|
|
if (poly.Length() <= 0) return;
|
|
|
|
int nSegNum = poly.TotalSegments();
|
|
for(int i = 0; i < nSegNum; i++) {
|
|
XDirectionCurve cvSeg;
|
|
poly.Nth(i, cvSeg);
|
|
|
|
if(cvSeg.Is(CURVE_LINE)) {
|
|
Append(new XPoint(cvSeg.StartPoint()));
|
|
} else {
|
|
double intAng = cvSeg.GetBulge();
|
|
int nDiv = 30;
|
|
if(cvSeg.Is(CURVE_ARC))
|
|
nDiv = TchExport::GetCirDivNum(cvSeg.GetArc().GetRadius(), _AS_SYS_UNIT(TchGeLib::g_nCirDeviation));
|
|
|
|
int nStep = AS_INT(fabs(intAng)/PI/2.0*nDiv);// how many sections
|
|
double nDistStep = cvSeg.GetLength()/nStep;
|
|
for(int j=0; j<nStep; j++) {
|
|
XPointDir2d ptE;
|
|
cvSeg.Polar(nDistStep*j, ptE);
|
|
Append(new XPoint(ptE));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 以基点为中心均分顶点
|
|
void XContour::Divide()
|
|
{
|
|
int nCount = Length();
|
|
if (nCount <= 0) return;
|
|
|
|
DList<XPoint> lstVertex;
|
|
for (int i = 0; i < nCount; i++) {
|
|
XPoint ptThis = *(*this)[i];
|
|
lstVertex.Append(new XPoint(ptThis));
|
|
}
|
|
Reset();
|
|
|
|
const double dAngleTotal = PI*2;
|
|
for (int nVertex=0; nVertex<m_nVertexNum; nVertex++) {
|
|
double dAngle = dAngleTotal*nVertex/m_nVertexNum;
|
|
for (int i=0; i<nCount; i++ ) {
|
|
XPoint ptOnContour;
|
|
if (Intersection(dAngle,m_ptWeightCenter,*lstVertex[i],
|
|
*lstVertex[(i+1)%nCount],ptOnContour)) {
|
|
Append(new XPoint(ptOnContour));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 以基点为中心均分顶点
|
|
void XContour::Divide(const DList<double>& lstOtherAngle)
|
|
{
|
|
int nCount = Length();
|
|
if (nCount <= 0) return;
|
|
|
|
DList<XPoint> lstVertex;
|
|
for (int i = 0; i < nCount; i++) {
|
|
XPoint ptThis = *(*this)[i];
|
|
lstVertex.Append(new XPoint(ptThis));
|
|
}
|
|
Reset();
|
|
|
|
const double dAngleTotal = PI*2;
|
|
int nOther = lstOtherAngle.Length();
|
|
for (int nVertex=0; nVertex<m_nVertexNum; nVertex++) {
|
|
double dPreAngle = dAngleTotal*nVertex/m_nVertexNum;
|
|
double dNextAngle = dAngleTotal*(nVertex+1)/m_nVertexNum;
|
|
|
|
for (int i=0; i<nCount; i++ ) {
|
|
XPoint ptOnContour;
|
|
if (Intersection(dPreAngle,m_ptWeightCenter,*lstVertex[i],
|
|
*lstVertex[(i+1)%nCount],ptOnContour)) {
|
|
Append(new XPoint(ptOnContour));
|
|
break;
|
|
}
|
|
}
|
|
|
|
//新增加的其他的角度
|
|
for (int j=0; j<nOther; j++) {
|
|
double dAngle = lstOtherAngle[j];
|
|
if (dAngle>dPreAngle && dAngle<dNextAngle) {
|
|
for (int i=0; i<nCount; i++ ) {
|
|
XPoint ptOnContour;
|
|
if (Intersection(dAngle,m_ptWeightCenter,*lstVertex[i],
|
|
*lstVertex[(i+1)%nCount],ptOnContour)) {
|
|
Append(new XPoint(ptOnContour));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL XContour::Intersection(const double dAngleRayLine,
|
|
const XPoint& ptOriginRayLine,
|
|
const XPoint& ptStart,
|
|
const XPoint& ptEnd,
|
|
XPoint& ptResult) const
|
|
{
|
|
double X0 = ptOriginRayLine.x, Y0 = ptOriginRayLine.y;
|
|
double X1 = ptStart.x, Y1 = ptStart.y;
|
|
double X2 = ptEnd.x, Y2 = ptEnd.y;
|
|
double alfa = dAngleRayLine;
|
|
double beta = atan2(Y2-Y1, X2-X1);
|
|
double sinBetaMinusAlfa = sin(beta-alfa);
|
|
double Xp, Yp;
|
|
|
|
if (fabs(sinBetaMinusAlfa)>1.0E-9) { // ZJQ Modify here
|
|
double t = ((X1-X0)*sin(beta)-(Y1-Y0)*cos(beta))/sinBetaMinusAlfa;
|
|
Xp = X0 + t*cos(alfa);
|
|
Yp = Y0 + t*sin(alfa);
|
|
double dx=fabs(X1-X2), dx1=fabs(Xp-X1), dx2=fabs(X2-Xp);
|
|
double dy=fabs(Y1-Y2), dy1=fabs(Yp-Y1), dy2=fabs(Y2-Yp);
|
|
double angle=atan2(Yp-Y0, Xp-X0);
|
|
|
|
//double PI2=PI*2;//removed by whl on 060406
|
|
|
|
while(alfa < -1.0E-9) alfa += PI2;
|
|
while(alfa > 2*PI) alfa -= PI2;
|
|
while(angle < -1.0E-9) angle += PI2;
|
|
|
|
if (fabs(angle-alfa) < ACCURACY &&
|
|
fabs(dx-(dx1+dx2)) < ACCURACY &&
|
|
fabs(dy-(dy1+dy2)) < ACCURACY) {
|
|
ptResult = XPoint(Xp,Yp,ptOriginRayLine.z);
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL XContour::IsValid() const
|
|
{
|
|
return m_nVertexNum>=3 && Length()==m_nVertexNum;
|
|
}
|
|
|
|
void XContour::GetAngles(DList<double>& lstAngle) const
|
|
{
|
|
lstAngle.Reset();
|
|
|
|
int nNum = Length();
|
|
for (int i=0; i<nNum; i++) {
|
|
XPoint ptThis = (*this)[i];
|
|
double dAngle = ads_angle(m_ptWeightCenter,ptThis);
|
|
lstAngle.Append(new double(dAngle));
|
|
}
|
|
}
|
|
|
|
void XContour::GetRadius(DList<double>& lstRadiu) const
|
|
{
|
|
lstRadiu.Reset();
|
|
|
|
int nNum = Length();
|
|
for (int i=0; i<nNum; i++) {
|
|
XPoint ptThis = (*this)[i];
|
|
double dRadiu = m_ptWeightCenter.Distance(ptThis);
|
|
lstRadiu.Append(new double(dRadiu));
|
|
}
|
|
}
|
|
|
|
double XContour::GetPerimeter() const
|
|
{
|
|
double dPerimeter=0;
|
|
XPoly2D polyThis(1);
|
|
AsPoly2D(polyThis);
|
|
dPerimeter = polyThis.Distance2d();
|
|
|
|
return dPerimeter;
|
|
}
|
|
|
|
double XContour::GetRadius(double dAngle) const
|
|
{
|
|
double dRadius=0;
|
|
|
|
//double PI2 = 2*PI;//removed by whl on 060406
|
|
|
|
while(dAngle<0)
|
|
dAngle += PI2;
|
|
while(dAngle>=PI2)
|
|
dAngle -= PI2;
|
|
|
|
if(m_nVertexNum!=0) {
|
|
double dStepAngle=PI2/m_nVertexNum;
|
|
int nThis=int(dAngle/dStepAngle);
|
|
if (nThis<=Length()) {
|
|
XPoint ptThis = (*this)[nThis];
|
|
XPoint ptNext = (*this)[(nThis+1)%Length()];
|
|
double dDistanceThis=m_ptWeightCenter.Distance(ptThis);
|
|
double dDistanceNext=m_ptWeightCenter.Distance(ptNext);
|
|
double dToThisAngle=dAngle-nThis*dStepAngle;
|
|
dRadius = dDistanceThis +
|
|
(dDistanceNext-dDistanceThis)*dToThisAngle/dStepAngle;
|
|
}
|
|
}
|
|
|
|
return dRadius;
|
|
}
|
|
|
|
double XContour::GetArea() const
|
|
{
|
|
double dArea=0;
|
|
XPoly2D polyThis(1);
|
|
AsPoly2D(polyThis);
|
|
dArea = polyThis.Area();
|
|
|
|
return dArea;
|
|
}
|
|
|
|
XPoint XContour::GetWeightCenter() const
|
|
{
|
|
return m_ptWeightCenter;
|
|
}
|
|
|
|
|
|
//********************* XContour2D BEGIN ***********************//
|
|
|
|
XContour2D::XContour2D()
|
|
{
|
|
}
|
|
|
|
XContour2D::XContour2D(const XPoly2D& polySrc,
|
|
const XPoint& ptBase,
|
|
int nVertexNum,
|
|
const DList<double>& lstOtherAngle)
|
|
{
|
|
Init(polySrc,ptBase,nVertexNum,lstOtherAngle);
|
|
}
|
|
|
|
XContour2D::XContour2D(const XContour2D& src)
|
|
{
|
|
m_nVertexNum = src.m_nVertexNum;
|
|
m_ptBase = src.m_ptBase;
|
|
int nCount = src.Length();
|
|
for (int i = 0; i < nCount; i++) {
|
|
Append(new XPoint(src[i]));
|
|
}
|
|
}
|
|
|
|
XContour2D::~XContour2D()
|
|
{
|
|
}
|
|
|
|
|
|
void XContour2D::Init(const XPoly2D& polySrc,
|
|
const XPoint& ptBase,
|
|
int nVertexNum,
|
|
const DList<double>& lstOtherAngle)
|
|
{
|
|
assert(m_nVertexNum >= 3);
|
|
if (polySrc.Length() <= 0) return ;
|
|
if (Length()>0) Reset();
|
|
|
|
m_ptBase = ptBase;
|
|
m_nVertexNum = nVertexNum;
|
|
double dElev = m_ptBase.z;
|
|
XPoly2D poly = polySrc;
|
|
poly.SetElevation(dElev);
|
|
|
|
Poly2DToVertexs(poly);
|
|
m_ptWeightCenter = ::GetWeightCenter(poly);
|
|
if (lstOtherAngle.Length()>0) {
|
|
Divide(lstOtherAngle);
|
|
}
|
|
else {
|
|
Divide();
|
|
}
|
|
}
|
|
|
|
BOOL XContour2D::IsValid() const
|
|
{
|
|
return XContour::IsValid();
|
|
}
|
|
|
|
double XContour2D::GetBaseRadius() const
|
|
{
|
|
return m_ptWeightCenter.Distance(m_ptBase);
|
|
}
|
|
|
|
double XContour2D::GetBaseAngle() const
|
|
{
|
|
return ads_angle(m_ptWeightCenter,m_ptBase);
|
|
}
|
|
|
|
//基点与中心点的距离/该方向上的半径
|
|
double XContour2D::GetBaseScale() const
|
|
{
|
|
double dBaseRadius=GetBaseRadius();
|
|
double dBaseAngle=GetBaseAngle();
|
|
double dRadius=GetRadius(dBaseAngle);
|
|
if (fabs(dRadius)>_DIST_SNAP) // ZJQ Modify here
|
|
return dBaseRadius/dRadius;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
//********************** XContour3D BEGIN *********************//
|
|
|
|
XContour3D::XContour3D()
|
|
{
|
|
m_vtNormal = XVector3D(0,0,1);
|
|
}
|
|
|
|
XContour3D::XContour3D(const DList<XPoint>& src,
|
|
const XPoint& ptBase,
|
|
const XPoint& ptCenter,
|
|
const XVector3D& vtNormal)
|
|
{
|
|
m_vtNormal = vtNormal;
|
|
m_ptCenter = ptCenter;
|
|
m_ptBase = ptBase;
|
|
Init(src);
|
|
}
|
|
|
|
XContour3D::XContour3D(const XContour2D& src,
|
|
const XVector3D& vtNormal)
|
|
{
|
|
m_vtNormal = vtNormal;
|
|
m_ptCenter = src.GetWeightCenter();
|
|
m_ptBase = src.m_ptBase;
|
|
Init(src);
|
|
}
|
|
|
|
XContour3D::XContour3D(const XContour3D& src)
|
|
{
|
|
m_vtNormal = src.m_vtNormal;
|
|
m_ptBase = src.m_ptBase;
|
|
m_ptCenter = src.m_ptCenter;
|
|
Init(src);
|
|
}
|
|
|
|
|
|
XContour3D::~XContour3D()
|
|
{
|
|
}
|
|
|
|
|
|
XContour3D & XContour3D::operator = (const XContour3D& src)
|
|
{
|
|
if (Length()>0) Reset();
|
|
m_vtNormal = src.m_vtNormal;
|
|
m_ptBase = src.m_ptBase;
|
|
m_ptCenter = src.m_ptCenter;
|
|
Init(src);
|
|
return *this;
|
|
}
|
|
|
|
void XContour3D::Init(const DList<XPoint>& src)
|
|
{
|
|
int nCount = src.Length();
|
|
for (int i=0; i<nCount; i++) {
|
|
Append(new XPoint(src[i]));
|
|
}
|
|
}
|
|
|
|
void XContour3D::
|
|
RotateBy(const double dAngle,const XVector3D& vtAxis,const XPoint& ptBase)
|
|
{
|
|
int nCount = Length();
|
|
AcGePoint3d ptTemp;
|
|
for (int i=0; i<nCount; i++ ) {
|
|
XPoint &ptThis = *(*this)[i];
|
|
ptTemp = ptThis;
|
|
ptTemp.rotateBy(dAngle, vtAxis, ptBase);
|
|
ptThis = ptTemp;
|
|
}
|
|
ptTemp = m_ptBase;
|
|
ptTemp.rotateBy(dAngle, vtAxis, ptBase);
|
|
m_ptBase = ptTemp;
|
|
|
|
ptTemp = m_ptCenter;
|
|
ptTemp.rotateBy(dAngle, vtAxis, ptBase);
|
|
m_ptCenter = ptTemp;
|
|
|
|
AcGeVector3d vtTemp = m_vtNormal;
|
|
vtTemp.rotateBy(dAngle, vtAxis);
|
|
m_vtNormal = vtTemp;
|
|
}
|
|
|
|
void XContour3D::
|
|
ScaleBy(const double dFactor,const XPoint& ptBase)
|
|
{
|
|
int nCount = Length();
|
|
AcGePoint3d ptTemp;
|
|
for (int i=0; i<nCount; i++ ) {
|
|
XPoint &ptThis = *(*this)[i];
|
|
ptTemp = ptThis;
|
|
ptTemp.scaleBy(dFactor, ptBase);
|
|
ptThis = ptTemp;
|
|
}
|
|
ptTemp = m_ptBase;
|
|
ptTemp.scaleBy(dFactor, ptBase);
|
|
m_ptBase = ptTemp;
|
|
|
|
ptTemp = m_ptCenter;
|
|
ptTemp.scaleBy(dFactor, ptBase);
|
|
m_ptCenter = ptTemp;
|
|
}
|
|
|
|
void XContour3D::RotateTo(const XPoint &ptPath,const XVector3D& vtDir)
|
|
{
|
|
double dAngle = ads_angle(XPoint(),vtDir);
|
|
dAngle = CT_std_angle(dAngle-PI/2);
|
|
ads_matrix mat;
|
|
ptPath.GetRotationMatrix(dAngle, mat);
|
|
|
|
TransUCS(mat);
|
|
m_ptBase.TransformBy(mat);
|
|
m_ptCenter.TransformBy(mat);
|
|
}
|
|
|
|
void XContour3D::
|
|
AttachOn(const XPoint& ptOnPlane,const XVector3D& vtPlaneNormal)
|
|
{
|
|
MoveTo(ptOnPlane);
|
|
RotateTo(ptOnPlane,vtPlaneNormal);
|
|
|
|
AcGeVector3d vtNormal(m_vtNormal);
|
|
vtNormal.z *= -1;
|
|
XVector3D vtRotateAxis = vtNormal.crossProduct(vtPlaneNormal);
|
|
double dRotateAngle = vtNormal.angleTo(vtPlaneNormal, vtRotateAxis);
|
|
RotateBy(dRotateAngle, vtRotateAxis, ptOnPlane);
|
|
}
|
|
|
|
void XContour3D::MoveTo(const XPoint& ptDestine)
|
|
{
|
|
XVector3D vtOff = ptDestine - m_ptBase;
|
|
|
|
int nCount = Length();
|
|
for (int i=0; i<nCount; i++ ) {
|
|
XPoint &ptThis = *(*this)[i];
|
|
ptThis += vtOff;
|
|
}
|
|
m_ptBase += vtOff;
|
|
m_ptCenter += vtOff;
|
|
}
|
|
|
|
|
|
|
|
|
|
XExtendEnd::XExtendEnd()
|
|
{
|
|
}
|
|
|
|
XExtendEnd::XExtendEnd(const XPoly2D& polySrc,
|
|
const XPoint& ptBase)
|
|
{
|
|
Init(polySrc,ptBase);
|
|
}
|
|
|
|
XExtendEnd::XExtendEnd(const XExtendEnd& src)
|
|
{
|
|
m_ptBase = src.m_ptBase;
|
|
m_ptLeft = src.m_ptLeft;
|
|
m_ptRight = src.m_ptRight;
|
|
|
|
}
|
|
|
|
XExtendEnd::~XExtendEnd()
|
|
{
|
|
}
|
|
|
|
|
|
void XExtendEnd::Init(const XPoly2D& polySrc,
|
|
const XPoint& ptBase)
|
|
{
|
|
m_ptBase = ptBase;
|
|
polySrc.GetExtend(m_ptLeft,m_ptRight);
|
|
m_ptLeft.y = m_ptBase.y;
|
|
m_ptLeft.z = m_ptBase.z;
|
|
m_ptRight.y = m_ptBase.y;
|
|
m_ptRight.z = m_ptBase.z;
|
|
}
|
|
|
|
double XExtendEnd::GetDistance() const
|
|
{
|
|
return m_ptLeft.Distance(m_ptRight);
|
|
}
|
|
|
|
void XExtendEnd::ScaleBy(const double dFactor,
|
|
const XPoint& ptBase,
|
|
BOOL bBaseScale)
|
|
{
|
|
AcGePoint3d ptTemp;
|
|
|
|
ptTemp = m_ptLeft;
|
|
ptTemp.scaleBy(dFactor, ptBase);
|
|
m_ptLeft = ptTemp;
|
|
|
|
ptTemp = m_ptRight;
|
|
ptTemp.scaleBy(dFactor, ptBase);
|
|
m_ptRight = ptTemp;
|
|
|
|
if(bBaseScale) {
|
|
ptTemp = m_ptBase;
|
|
ptTemp.scaleBy(dFactor, ptBase);
|
|
m_ptBase = ptTemp;
|
|
}
|
|
}
|
|
|
|
|
|
void XExtendEnd::RotateBy(const double dAngle,
|
|
const XVector3D& vtAxis,
|
|
const XPoint& ptBase)
|
|
{
|
|
AcGePoint3d ptTemp;
|
|
|
|
ptTemp = m_ptBase;
|
|
ptTemp.rotateBy(dAngle, vtAxis, ptBase);
|
|
m_ptBase = ptTemp;
|
|
|
|
ptTemp = m_ptLeft;
|
|
ptTemp.rotateBy(dAngle, vtAxis, ptBase);
|
|
m_ptLeft = ptTemp;
|
|
|
|
ptTemp = m_ptRight;
|
|
ptTemp.rotateBy(dAngle, vtAxis, ptBase);
|
|
m_ptRight = ptTemp;
|
|
}
|
|
|
|
void XExtendEnd::MoveTo(const XPoint& ptDestine)
|
|
{
|
|
XVector3D vtOff=ptDestine-m_ptBase;
|
|
m_ptBase += vtOff;
|
|
m_ptLeft += vtOff;
|
|
m_ptRight+= vtOff;
|
|
}
|
|
|
|
XPoint XExtendEnd::GetCenter() const
|
|
{
|
|
XPoint ptCenter;
|
|
Midpoint(m_ptRight,m_ptLeft,ptCenter);
|
|
return ptCenter;
|
|
}
|
|
|
|
void XExtendEnd::AttachOn(const XPoint& ptOnPath,
|
|
const XVector3D& vtPathNormal)
|
|
{
|
|
MoveTo(ptOnPath);
|
|
double dAngle=ads_angle(XPoint(0,0,0),vtPathNormal);
|
|
RotateBy(dAngle, AcGeVector3d(0,0,1), ptOnPath);
|
|
}
|
|
|
|
|
|
|
|
|
|
TPolyPath::TPolyPath():
|
|
m_bLineDeviation(FALSE)
|
|
{
|
|
extern double g_nCirDeviation;
|
|
m_dDeviation = _AS_SYS_UNIT(TchGeLib::g_nCirDeviation);
|
|
}
|
|
|
|
TPolyPath::TPolyPath(const XPoly2D& polySrc,
|
|
BOOL bLineDeviation)
|
|
{
|
|
extern double g_nCirDeviation;
|
|
m_dDeviation = _AS_SYS_UNIT(TchGeLib::g_nCirDeviation);
|
|
Init(polySrc,bLineDeviation);
|
|
}
|
|
|
|
TPolyPath::TPolyPath(const XPoly2D& polySrc,
|
|
double dDeviation,
|
|
BOOL bLineDeviation)
|
|
{
|
|
extern double g_nCirDeviation;
|
|
m_dDeviation = dDeviation;
|
|
Init(polySrc,bLineDeviation);
|
|
}
|
|
|
|
TPolyPath::~TPolyPath()
|
|
{
|
|
}
|
|
|
|
|
|
void TPolyPath::Init(const XPoly2D& polySrc,
|
|
BOOL bLineDeviation)
|
|
{
|
|
extern int GetCirDivNum(double r, double h);
|
|
|
|
Reset();
|
|
m_bLineDeviation = bLineDeviation;
|
|
if (polySrc.Length()<=0) return;
|
|
|
|
Append(new XPoint(polySrc[0]));
|
|
|
|
int nSegNum = polySrc.TotalSegments();
|
|
for(int i = 0; i < nSegNum; i++) {
|
|
XDirectionCurve cvSeg;
|
|
polySrc.Nth(i, cvSeg);
|
|
|
|
if(cvSeg.Is(CURVE_LINE)) {
|
|
if (m_bLineDeviation) {//直线也分段
|
|
double dLineDistance = cvSeg.GetLength();
|
|
|
|
//直线分段(周长作为半径)
|
|
int nDiv = TchExport::GetCirDivNum(dLineDistance,m_dDeviation);
|
|
int nStep = AS_INT(nDiv/10);
|
|
if (nStep <= 0) nStep++;
|
|
double nDistStep = dLineDistance/nStep;
|
|
|
|
for(int j=0; j<nStep; j++) {
|
|
XPointDir2d ptE;
|
|
cvSeg.Polar(nDistStep*(j+1), ptE);
|
|
Append(new XPoint(ptE));
|
|
}
|
|
} else {
|
|
Append(new XPoint(cvSeg.EndPoint()));
|
|
}
|
|
} else {
|
|
double intAng = cvSeg.GetBulge();
|
|
int nDiv = 30;
|
|
if(cvSeg.Is(CURVE_ARC))
|
|
nDiv = TchExport::GetCirDivNum(cvSeg.GetArc().GetRadius(), m_dDeviation);
|
|
|
|
int nStep = AS_INT(fabs(intAng)/PI/2.0*nDiv);// how many sections
|
|
double nDistStep = cvSeg.GetLength()/nStep;
|
|
for(int j=0; j<nStep; j++) {
|
|
XPointDir2d ptE;
|
|
cvSeg.Polar(nDistStep*(j+1), ptE);
|
|
Append(new XPoint(ptE));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Distance from the 1st vertex.
|
|
double TPolyPath::GetDistAtVertex(int index) const
|
|
{
|
|
double dDistance = 0;
|
|
|
|
if (0<=index && index<Length()) {
|
|
for ( int i=1; i<=index; i++ ) {
|
|
XPoint ptThis = (*this)[i-1];
|
|
XPoint ptNext = (*this)[i];
|
|
dDistance += ptThis.Distance(ptNext);
|
|
}
|
|
}
|
|
return dDistance;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
XTriangleWeiCen::~XTriangleWeiCen()
|
|
{
|
|
|
|
}
|
|
|
|
|
|
XPoint XTriangleWeiCen::WeightCenter()
|
|
{
|
|
XPoint ptWeightCenter;
|
|
|
|
ptWeightCenter.x = (vertex1.x + vertex2.x + vertex3.x)/3;
|
|
ptWeightCenter.y = (vertex1.y + vertex2.y + vertex3.y)/3;
|
|
ptWeightCenter.z = (vertex1.z + vertex2.z + vertex3.z)/3;
|
|
|
|
return ptWeightCenter;
|
|
}
|
|
|
|
double XTriangleWeiCen::Area()
|
|
{
|
|
AcGeVector3d vtA = vertex1.AsAcGeVector3d();
|
|
AcGeVector3d vtB = vertex2.AsAcGeVector3d();
|
|
AcGeVector3d vtC = vertex3.AsAcGeVector3d();
|
|
AcGeVector3d vtAB = vtB - vtA;
|
|
AcGeVector3d vtAC = vtC - vtA;
|
|
AcGeVector3d vtCrossProduct = vtAB.crossProduct(vtAC);
|
|
AcGeVector3d vtZAxis(0,0,1);
|
|
|
|
double dArea = 0.5*vtCrossProduct.length();
|
|
if ( vtCrossProduct.angleTo(vtZAxis) >= PI )
|
|
dArea *= -1;
|
|
|
|
return dArea;
|
|
}
|
|
|
|
// 取得重心
|
|
XPoint GetWeightCenter(const XPoly2D& poly)
|
|
{
|
|
extern int GetCirDivNum(double r, double h);
|
|
extern double g_nCirDeviation;
|
|
if (poly.Length()<=0) return XPoint(0,0,0);
|
|
|
|
XPoint ptWeightCenter;
|
|
|
|
//顶点链表
|
|
DList<XPoint> lstVertex;
|
|
int nSegNum = poly.TotalSegments();
|
|
for(int k = 0; k < nSegNum; k++) {
|
|
XDirectionCurve cvSeg;
|
|
poly.Nth(k, cvSeg);
|
|
|
|
if(cvSeg.Is(CURVE_LINE)) {
|
|
lstVertex.Append(new XPoint(cvSeg.StartPoint()));
|
|
} else {
|
|
double intAng = cvSeg.GetBulge();
|
|
int nDiv = 30;
|
|
if(cvSeg.Is(CURVE_ARC))
|
|
nDiv = TchExport::GetCirDivNum(cvSeg.GetArc().GetRadius(), _AS_SYS_UNIT(TchGeLib::g_nCirDeviation));
|
|
|
|
int nStep = AS_INT(fabs(intAng)/PI/2.0*nDiv);// how many sections
|
|
double nDistStep = cvSeg.GetLength()/nStep;
|
|
for(int j=0; j<nStep; j++) {
|
|
XPointDir2d ptE;
|
|
cvSeg.Polar(nDistStep*j, ptE);
|
|
lstVertex.Append(new XPoint(ptE));
|
|
}
|
|
}
|
|
}
|
|
|
|
//转换为三角形,计算三角形重心
|
|
int nStep = lstVertex.Length()-1;
|
|
if (nStep < 0) {
|
|
return XPoint(0,0,0);
|
|
}
|
|
else if (nStep == 0) {
|
|
ptWeightCenter = *lstVertex[0];
|
|
}
|
|
else {
|
|
double dSigemaMiXi=0, dSigemaMiYi=0, dSigemaMi=0;
|
|
for (int n=1; n<nStep; n++ ) {
|
|
XPoint pt1=*lstVertex[0];
|
|
XPoint pt2=*lstVertex[n];
|
|
XPoint pt3=*lstVertex[n+1];
|
|
//adsout << "\nTriangle=" << pt1 << pt2 << pt3;
|
|
XTriangleWeiCen triangleUnit(pt1,
|
|
pt2,pt3);
|
|
XPoint ptWi= triangleUnit.WeightCenter();
|
|
//adsout << "\nptWi=" << ptWi;
|
|
double dMi = triangleUnit.Area();
|
|
|
|
dSigemaMiXi = dSigemaMiXi + dMi*ptWi.x;
|
|
dSigemaMiYi = dSigemaMiYi + dMi*ptWi.y;
|
|
dSigemaMi = dSigemaMi + dMi;
|
|
}
|
|
|
|
if ( fabs(dSigemaMi)>1.0E-9 ) {
|
|
ptWeightCenter = XPoint(dSigemaMiXi/dSigemaMi,
|
|
dSigemaMiYi/dSigemaMi,(*lstVertex[0]).z);
|
|
} else {
|
|
ptWeightCenter = XPoint(0,0,0);
|
|
}
|
|
}
|
|
return ptWeightCenter;
|
|
}
|
|
|
|
|
|
|
|
// 取得周线顶点数(同分弧精度 g_nCirDeviation 相联系,有待修改)
|
|
int GetContourDivNum(double dPerimeter)
|
|
{
|
|
extern double g_nCirDeviation;
|
|
extern int GetCirDivNum(double r, double h);
|
|
//周长作为半径
|
|
int nDiv = TchExport::GetCirDivNum(dPerimeter/PI/2.0,_AS_SYS_UNIT(TchGeLib::g_nCirDeviation));
|
|
if (nDiv < 3) nDiv = 3;
|
|
|
|
return nDiv;
|
|
}
|