#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 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& lstOtherAngle) { int nCount = Length(); if (nCount <= 0) return; DList 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; nVertexdPreAngle && dAngle1.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& lstAngle) const { lstAngle.Reset(); int nNum = Length(); for (int i=0; i& lstRadiu) const { lstRadiu.Reset(); int nNum = Length(); for (int i=0; i=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& 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& 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& 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& src) { int nCount = src.Length(); for (int i=0; i= 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 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