////////////////////////////////////////////////////////////////////////////// //文件 Curve.h ///////////////////////////////////////////////////////////////////////////// // Curve.h: interface for the CCurve class. #if (_MSC_VER > 1000) #pragma once #endif // _MSC_VER > 1000 #ifndef _MSC_VER #pragma once #endif #ifndef AFX_EXT_CLASS #define AFX_EXT_CLASS Q_DECL_IMPORT #endif #include "Name.h" #include #include #include "../GBase/Point2D.h" #include "../GBase/Rect8.h" #include "../GBase/CrossPoint.h" #include "../TBase/TObjectList.h" #include "../GBase/BaseFunction.h" #include "../GBase/IOFile.h" #include "../InterfaceElements.h" using std::vector; using std::list; //typedef TList CCrossList; typedef TList CPositionList; namespace GObjects { class CMyCurve; //线段类 class AFX_EXT_CLASS VSegment { public: VSegment(void); // m_pt1 在m_pt2左侧 void Create(const GBase::CPoint2D& pt1, const GBase::CPoint2D& pt2); bool operator==(const VSegment& other) const; bool operator<(const VSegment& other) const; //生成线段 CMyCurve* CreateCurve(void) const; GBase::CPoint2D GetPt1(void) const; GBase::CPoint2D GetPt2(void) const; double GetLength(void) const; //获取斜率 double GetK(void) const; //是否平行 bool IsParallel(const VSegment& other) const; //pt是否在线上 bool IsPtOnSegment(const GBase::CPoint2D& pt) const; //两个线段是否有重合部分,首尾相接不算重合 bool HasRepeatedSection(const VSegment& other) const; private: double GetK(const GBase::CPoint2D& pt1, const GBase::CPoint2D& pt2) const; GBase::CPoint2D m_pt1; GBase::CPoint2D m_pt2; double m_k; }; class AFX_EXT_CLASS CMyCurve : public CName { public: CMyCurve(); CMyCurve(int num); CMyCurve(CMyCurve& cur); virtual ~CMyCurve(); //G_CLONE_ELEMENT(CCurve) virtual CString GetXmlType() { return _T("Pline"); } virtual void Clear(void); virtual GBase::CRect8 GetRect(void); ///< 获取曲线的最小外接矩形 added ww 2014-9-15 virtual void Offset(double dx, double dy); virtual void ScaleCoor(double xs, double ys, double dx, double dy); virtual void Rotate(double xs, double ys, double angle); virtual BOOL SetPoints(GBase::CPointList &dp, int nnPoint, BOOL IsAutoLocation = TRUE); virtual BOOL SetPoints(GBase::CPoint2D *pPts, int nnPoint, BOOL IsAutoLocation = TRUE); public: int Create(int num); int CreateCurveFromRect(GBase::CRect8* pRect); int CreateCurveFromRect(GBase::CRect8* pRect, int iBevel); //根据椭圆参数生成曲线,生成角度步长angleStep,type=0:Arc,1:Chord, 2:Pie int CreateCurveFromEllipse(GBase::CPoint2D centerPoint, GBase::CSize8 szRadius, double angleStep, double arc1 = 0.0, double arc2 = 360.0, int type = 0); int CreateCurveFromEllipse(GBase::CRect8* pRect, double angleStep, double arc1 = 0.0, double arc2 = 360.0, int type = 0); int Read(CString strPathFile, long offset); int Read(IOFile& fr, double m_z); void Write(FILE* &fw); BOOL IsClosed(double dDistance = 1e-10); //是否是首尾闭合 void SetToClose(); int Cross(CMyCurve &c2, TList &xy); //int Trim(CCurve &m_curve,CDFile& fw); int FindIndex(double xx, double yy, double err);//查找最近的节点 BOOL LocationIsInRange(double l0); int IsInside(double xm, double ym); //点是否在曲线内 int IsInside(CMyCurve& curve); //判断curve是否在当前曲线内部,全部在内返回1,全部不在内返回0,部分在部分不在返回-1 BOOL IsInRange(GBase::CRect8& range); int CrossLine(double *linex, double *liney, TList &m_cross); //曲线与直线交点,成功返回1 失败返回0 x0,y0为直线上一点, (vx,vy)为直线向量方向 ,交点存于vector中 added by ww int CrossLine(double x0, double y0, double vx, double vy, vector& crpoints); void GetLocation(); void GetLocation3D(); void Reversal(); BOOL Extend(double extendLength, int sel);//延伸曲线,sel=0延伸头,sel=1延伸尾 void Smooth53(int ntimes); //五点三次光滑,ntimes = 光滑次数 //加密节点 void EncryptNode(int nMode, double step, BOOL bInteger); //由给定间隔加密曲线,bReserveVertex为true表示保留原始点 2019.3.12 void Infill(double dl, bool bVertexReserved = true); int RemoveSamePoint(double dMinDistance); //移除曲线中相同的节点,返回清除点的个数 int RedundantPoint(double dMinDistance); //冗余节点,返回冗余点的个数 //bReverse为是否反向获得曲线点数据, bAddHead是否将点利用AddHead插入到列表对,否则利用AddTail插入到列表尾 void GetPoint(GBase::CPointList &dp, BOOL bReverse = FALSE, BOOL bAddHead = FALSE); void GetPoint(CPointArr &dp, BOOL bReverse = FALSE, BOOL bAddHead = FALSE); BOOL GetPoint(int nIndex, GBase::dfPoint& dp); BOOL SetPoint(int nIndex, GBase::dfPoint& dp); void SetPoint(int nIndex, double x0, double y0); void SetPoint(int nIndex, double x0, double y0, double z0); int GetCurve(double l1, double l2, GBase::CPointList &dp, int bDoubleHeadTail = 1, BOOL bNoLineValue = FALSE); //指定起始序号,用顺序查找方式GetCurve,查找结束后返会l2之前的最近结点序号,最后一个参数表示是否对z插值 added by ww 2015-6-25 int GetCurve(int& startindex /* = 0*/, double l1, double l2, GBase::CPointList &dp, int bDoubleHeadTail = 1, BOOL bNoLineValue = FALSE, BOOL bIgnoreZ = FALSE); int GetCurveOther(double l1, double l2, GBase::CPointList &dp, int bDoubleHeadTail = 1, BOOL bNoLineValue = FALSE); int GetCoordinate(double m_location, double &x, double &y, double &z); int GetCoordinate(double m_location, GBase::CPoint3D& pt); //由指定的桩号点序号向后顺序查找location对应的点,找到后将序号定位到该桩号位置的前一结点处。 默认计算z值 added by ww 2015-9-29 int GetCoordinate(int& nIndex, double location, GBase::CPoint3D& pt, bool bCalcZ = true); //由指定的桩号点序号向后顺序查找location对应的点,找到后将序号定位到该桩号位置的前一结点处。 默认计算z值 added by ww 2015-10-12 int GetCoordinate(int& nIndex, double location, double& xx, double& yy); double GetAngle(double dLocation, GBase::CPoint3D* pCoor = NULL); //获得指定桩号处的角度 void GetRange(double& xmin, double& ymin, double& xmax, double& ymax, double* pzmin = 0, double* pzmax = 0, double invalidZ = 1e10); double operator [](int i); CMyCurve& operator =(const CMyCurve& t); int GetCount() { return num; } double Length(void); double Area(void); double xend(void); double yend(void); double lend(void); /** @brief 点到曲线的距离,l0为垂足的桩号, bAutoExtend表示求取距离时是否延长首尾*/ double PointDistance(double x0, double y0, double& l0, bool bAutoExtend = true); virtual int SetName(LPCTSTR lpString); virtual CString GetName(void); //判断叉积误差在dError范围内是否为直线 ww 2015-5-11 bool IsStraightLine(double dError = 1e-6); enum EClipType { ctIntersection = 0, ctUnion = 1, ctDifference = 2, ctXor = 3 }; //当前多边形切割多边形,返回结果多边形 int ClipPolygon(CMyCurve& subject, vector& resultPgns, EClipType eType); public: //曲线类型 static DWORD GetCurveType(CString str); static CString GetCurveTypeString(DWORD type); public: int m_type; int num; double *x, *y, *z, *l; int nPoint; //每个点属性值个数,x y z l 等 int ReturnPoint; //逆断层上下盘连接索引号 -1表示为正断层 BOOL bAutoLocation; protected: void _ClearDC(TPtrList &dc); int _CrossVC(double xm, int num, double *x, double *y, double *ycross); int _CrossVSort(double xm, int num, double *x, double *y, double *ycross); int GetOneValue(TPtrList &dc1); //断层统计部分 add Wangcw public: //一对点 class PointPair { public: PointPair(void) :dist(0.0), pt1(0, 0), pt2(0, 0) {}; bool operator<(const PointPair& other) { return dist < other.dist; } void GetDist(void) { dist = pt1.Distance(pt2); } double dist; GBase::CPoint2D pt1; GBase::CPoint2D pt2; }; /** @brief 得到闭合曲线的延伸长度*/ double GetClosureLength(); /** 得到闭合曲线的延伸长度,已知宽度*/ double GetClosureLength(double width); /** 得到曲线所有线段与x轴夹角的平均值,即曲线走向*/ double GetAverageAngle(); /** 得到曲线XY平面上宽度*/ bool GetClosureWidth(double& maxWid, double& minWid, double& aveWid); /** 在已知中心线集的情况下得到曲线XY平面上宽度(即断距)*/ bool GetClosureWidth(std::vector& skeletonCurves, double& maxWid, double& minWid, double& aveWid); /** 通过骨骼线集获取多边形宽度标记点, 以pt对的结构存入dstBdPoints*/ int GetPolygonWidthPoints(std::vector& skeletonCurves, std::list& dstBdPoints); /** 通过骨骼线集获取多边形宽度标记点, 以pt对的结构存入dstBdPoints*/ int GetPolygonWidthPoints(CMyCurve* skl, std::list& dstBdPoints); // /** 求线段与本线交点,*/ // bool GetLineCrossPoints(double x0, double y0, double k, PointPair& dstPP); /** 得到曲线Z高度差*/ bool GetClosureDZ(double& maxDZ, double& minDZ, double& aveDZ); //去除断线指示箭头 /**@brief 得到垂直于闭合圈走向的突出点,返回改点序号 ,可用于去除指示箭头, 默认筛选角度30度*/ int GetPerpendicularPoint(double filterAngle = 30); //点线距离3D add Wangcw public: /** @brief 该曲线到某三维点的最短距离*/ double PointDistance3D(double x0, double y0, double z0); /** @brief 曲线之间的平均距离*/ double CurveDistance3D(CMyCurve& curve); /**@brief 得到闭合曲线的中心点 ,失败返回false*/ bool GetClosureCenter(GBase::CPoint3D& cpt); //获取多边形内部任一点 bool GetInnerPoint(double& x0, double& y0); /**@brief 曲线多边形是否为顺时钟方向*/ bool IsClockWise(void); /**@brief 判断两条曲线是否相邻(至少两个公共点)*/ bool IsAdjacent(CMyCurve& other); /** @brief 当前曲线与闭合曲线连接 返回新曲线 ww 2016-10-28*/ CMyCurve* LinkCircle(CMyCurve& circle); /*isThisClockWise = 当前曲线是否顺时钟, isOtherClockWise = OTHER曲线是否顺时钟, isOtherInside = otherCircle是否在本 曲线内部 */ CMyCurve* LinkCircle(CMyCurve& circle, bool isThisClockwise, bool isOtherClockwise, bool isOtherInside); /** @brief 连接相邻接的闭合线*/ CMyCurve* LinkAdjacentCircle(CMyCurve& circle); /** @brief 当前曲线与闭合曲线连接 iNode为连接线对应本曲线结点,tarL为circle连接位置桩号ww 2019-5-8*/ CMyCurve* LinkCircle(CMyCurve& tarCircle, int iNode, double tarL); /** @brief 当前曲线与内部曲线连接 iNode为连接线对应本曲线结点,tarL为circle连接位置桩号, isThisClockWise = 当前曲线是否顺时钟, isOtherClockWise = OTHER曲线是否顺时钟, isOtherInside = otherCircle是否在本 曲线内部*/ CMyCurve* LinkCircle(CMyCurve& otherCircle, int iNode, double tarL, bool isThisClockwise, bool isOtherClockwise, bool isOtherInside); /** @brief 得到曲线集合中得到与当前曲线各节点距离最近的曲线指针 简便ww 2019.5.8*/ CMyCurve* GetNearestCurve(vector& curves,int* iNode = 0, double* tarL = 0,bool bQuickTrace= false); CMyCurve* GetNearestCurve(std::list& curves,int* iNode = 0, double* tarL = 0, bool bQuickTrace = false); /** @brief 获取曲线各节点到tarCurve的最近距离和对应结点序号 bQuickTrace = true则只考虑结点*/ double GetMinNodeCurveDist(CMyCurve& tarCurve,int& myNode, double& tarL, bool bQuickTrace = false); //获取方位角,X正向为0度,返回(-180,180] double GetAzimuthDegree(void); //获取方位角,y正向为0度,x正向为90度,返回 [0,360) double GetAzimuthDegree2(void); public: //static functions //获取相邻多边形的边界,外部邻接返回大边界,内部邻接生成挖空的凹形边界 返回个数 static int CreateUnitedBoundaries(vector& pgns, vector& borders); //获取多边形的线段集 static void GetBoundarySegs(vector& scrPgns, list& dstSegs); static CMyCurve* CreateBoundary(list& scrSegs); //两线段减去相同部分,得到不同部分的线段个数,若无相交(或仅有一点相交) 返回0 static int SubtractSegment(VSegment& v1, VSegment& v2, vector& dstSegs); protected: GBase::CBaseFunction pf; }; }; using namespace GObjects; extern "C" AFX_EXT_API bool WINAPI IsRepeated(const GBase::CPoint2D& pt1, const GBase::CPoint2D& pt2, double prec = 1e-4); //断层或边界曲线列表 typedef TObjectList CCurveList; extern "C" AFX_EXT_API void WINAPI Pline2Curve(CPolyline& pl, CMyCurve& cur); //拷贝polyline到curve vec extern "C" AFX_EXT_API void WINAPI CopyPlines2Curves(vector& scr, vector& dst); extern "C" AFX_EXT_API void WINAPI Curve2Pline(CMyCurve& cur, CPolyline& pl); //拷贝curvevec到polylinevec extern "C" AFX_EXT_API void WINAPI CopyCurves2Plines(vector& scr, vector& dst);