You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

307 lines
12 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

//////////////////////////////////////////////////////////////////////////////
//文件 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 <vector>
#include <list>
#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<CCrossPoint> CCrossList;
typedef TList<POSITION> 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<CCrossPoint> &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<CCrossPoint> &m_cross);
//曲线与直线交点成功返回1 失败返回0 x0,y0为直线上一点 (vx,vy为直线向量方向 交点存于vector<dfpoint>中 added by ww
int CrossLine(double x0, double y0, double vx, double vy, vector<GBase::dfPoint>& 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<CMyCurve*>& 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<CMyCurve*>& skeletonCurves, double& maxWid, double& minWid, double& aveWid);
/** 通过骨骼线集获取多边形宽度标记点, 以pt对的结构存入dstBdPoints*/
int GetPolygonWidthPoints(std::vector<CMyCurve*>& skeletonCurves, std::list<PointPair>& dstBdPoints);
/** 通过骨骼线集获取多边形宽度标记点, 以pt对的结构存入dstBdPoints*/
int GetPolygonWidthPoints(CMyCurve* skl, std::list<PointPair>& 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<CMyCurve*>& curves,int* iNode = 0, double* tarL = 0,bool bQuickTrace= false);
CMyCurve* GetNearestCurve(std::list<CMyCurve*>& 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<CMyCurve*>& pgns, vector<CMyCurve*>& borders);
//获取多边形的线段集
static void GetBoundarySegs(vector<CMyCurve*>& scrPgns, list<VSegment>& dstSegs);
static CMyCurve* CreateBoundary(list<VSegment>& scrSegs);
//两线段减去相同部分,得到不同部分的线段个数,若无相交(或仅有一点相交) 返回0
static int SubtractSegment(VSegment& v1, VSegment& v2, vector<VSegment>& 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<CMyCurve> 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<CPolyline*>& scr, vector<CMyCurve*>& dst);
extern "C" AFX_EXT_API void WINAPI Curve2Pline(CMyCurve& cur, CPolyline& pl);
//拷贝curvevec到polylinevec
extern "C" AFX_EXT_API void WINAPI CopyCurves2Plines(vector<CMyCurve*>& scr, vector<CPolyline*>& dst);