/************************************************************************************** 文 件 名:Contour2Polygon.h 主要功能: 生成等值线和附近等值线,断层,以及边界包围成的多边形区域 *****************************************************************************************/ #pragma once #ifndef AFX_EXT_CLASS #define AFX_EXT_CLASS Q_DECL_IMPORT #endif #include "MyCurve.h" #include "TBase/TMultiTree.h" #include "curvegraph.h" #include #include #include namespace GObjects { //class CPolygonTree; class AFX_EXT_CLASS CCon2Pgn : protected CCurveGraph { public: CCon2Pgn(void); virtual ~CCon2Pgn(void); void ClearAll(void); void SetContours(vector& vec); void SetFlts(vector& scrFlts); void SetBorder(CMyCurve& border); //设置等值线延伸长度 void SetExtensivePara(double dext) { m_dext = dext; } double GetExtensivePara(void) const { return m_dext; } //过滤边界外的等值线和断层 void FilterOutsideContours(void); //生成等值线 void CreatePolygons(void); // //输出多边形到文件中 ,decimalPlaces 为最多保留几位小数 void WritePolygons(char* strOutput, int decimalPlaces = 2); //输出纯多边形到文件中,没有颜色等信息,曲线名为包围线的名字集合,由','分割 void WritePurePolygons(char* strOutput); vector& GetPolygons() { return m_dstPolygons; } //根据多边形散点z值获取当前多边形曲线z值 double GetPolygonValue(CMyCurve& curve); //获取颜色 由输入的等值线值获取该等值线颜色 COLORREF GetColor(double val); //psubj是否在prange中 返回在内部或部分在内部 static bool IsCurveInside(CMyCurve* pRange, CMyCurve* pSubj); //override protected: //获取曲线间交点 可按照具体曲线类型重写 virtual int GetCrossPoints(void); //获取下一结点 重写基类函数,如果该段已经查找过,返回0 virtual PT3Node* GetNextNode(PT3Node* pLastNode, PT3Node* pCurrentNode); //开放等值线生成闭合区域相关 public: //交叉点转向位置 class STurning { public: /* SFltSec(void);*/ //自动整理 小在前 大在后 STurning(CCurveGraph::PT3Node* pLast, CCurveGraph::PT3Node* pCurrent, CCurveGraph::PT3Node* pNext, ESide eside); /*bool operator==(const SFltSec& pd2) const;*/ bool operator<(const STurning& pt2) const; private: CCurveGraph::PT3Node* mp1; CCurveGraph::PT3Node* mp2; CCurveGraph::PT3Node* mp3; //bool mbForw; //是否沿着断线方向 CCurveGraph::ESide mSide; }; ////整理边界,以最左侧点为起点 暂时不用 //void SortBorder(void); ////获取边界,断层与等值线的交点,存在交点容器中 //void GetAllCrossPoints(void); ////获取所有等值线对应的边界交点和每条断线上对应的等值线交点 //void GetContourNodes(void); //追踪所有多边形 void Trace(void); //追踪边界对应的多边形 void TraceBorderPolygons(CMyCurve* border); //追踪边界(或断层)上指定交叉点线段对应的闭合多边形结点list,根据list生成ccurve,存入m_outputPolygons中 bool TraceFltSegPolygon(CMyCurve* curve, SCRPoint* startSCRPt, bool bBorder); //追踪一根断层对应的多边形 void TraceFltPolygons(CMyCurve* flt); //追踪一条等值线对应的多边形 ww 2019 void TraceContourPolygons(CMyCurve* pContour); //由结点链表生成一个开放多边形 CMyCurve* CreateOneOpenPolygon(list& lstNodes); //构建以每个开放等值线多边形为根,闭合等值线为结点的树,若无子结点 直接添加到输出容器中 // m_bCheckZ在此函数进行控制 void TraceOutputPolygons(void); void EnableCheckZ(bool b) { m_bCheckZ = b; } //members private: //输入的成员变量 double m_dext; CMyCurve* m_pBorder; vector m_contours; //输入等值线 外部指针 vector m_bd_faults; //输入的边界地址和断层 外部指针 第一个为边界 //最终输出的多边形 vector m_dstPolygons; //构建闭合多边形的树状图并输出多边形 ww 2019.4.16 void TraceOutputCircles(list& closingCurves); //过滤openpolygons的包含关系 void CombineOpenPolygons(void); bool IsFltZ(double z); //获取边界上的交叉点的结点指针 存入m_borderCxNodes void GetBorderCXNodes(void); //由名称z值过滤最终多边形 m_checkZ此处起作用 void FilterDstPolygons(void); //由名称判断该多边形是否legal bool IsPolygonLegal(CMyCurve* pgn); //判断结点是否可用 用于基类追踪下一点时使用 virtual bool IsNodeAvaliable(PT3Node* pNode) override; //删除断层内部或者边界外部的非法多边形 void EraseIllegalPolygons(vector& srcCurves); private: set m_tracedTurnings; // tmp 记录已经追踪到的交叉点和相连结点的线段 //中间变量 private: //计算出的中间成员变量 vector m_openContPolygons; //开放等值线生成的闭合多边形 vector m_circleIndexes; //闭合等值线序号 map > m_mapFltNodes; //存储每一根断层上所有的结点序号, 按照断线桩号进行排列 vector m_rectFlts; //所有断层所在矩形 //set m_fltPolygons; //由断层追踪出来的多边形 //等值线最大值,最小值和间距 double m_maxVal; double m_minVal; double m_conStep; const double m_dFLTZ; //缺省断线和边界z值 bool m_bCheckZ; //是否检查Z值的有效性 set m_borderCxNodes; //记录边界上的交叉点 set m_borderPolygons; //存储至少一边在边界上的多边形 bool m_bBorderTracing; //是否在追踪边界 }; //多边形树中一个结点 typedef TTreeNode CPgnNode; typedef TMultiTree CPgnTree; //闭合多边形树,该树第一级为一系列PolygonTreeNod根节点 每个nod包含0个或多个根节点 class AFX_EXT_CLASS CPolygonTree { public: CPolygonTree(); ~CPolygonTree(); void Clear(); void SetRootCurve(CMyCurve* pRootCurve); CMyCurve* GetRootCurve(void); void SetChildCurves(vector& childCurves); void AddChildCurve(CMyCurve* pChild); //根据多边形包含关系生成树 void BuildTree(void); //根据子曲线层级关系生成树 minArea为过滤面积 bool BuildTreeWithHierarchy(vector< vector >& hierarchy, double minArea = -100); //设置最小过滤面积 void SetFilterArea(double area) { m_minArea = area; } //生成多个多边形 void CreatePolygons(void); //输出的环状圈闭 析构会自动删除 vector m_outCurves; CPgnTree& GetTree(void) { return m_tree; } //递归函数 根据当前节点与其子结点生成一条多边形曲线,存入m_outCurves bQuickTrace为快速查找 void TracePolygons(CPgnNode* pNode,bool bCombineAdjacent = true, bool bQuickTrace= false); //快速查找CPgnNode* pNode与其子结点生成一条多边形曲线,存入m_outCurves void QuickTracePolygons(CPgnNode* pNode, bool bCombineAdjacent = false, bool bQuickTrace = true); //种子曲线连接所有子曲线,生成一条合并的曲线 static CMyCurve* CreateCombinedCurve(CMyCurve* pSeed, list& candidates); private: //根据曲线,并生成子结点并插入到树中 void CreateNInsertChild(CMyCurve* pCurve); //根据层级关系,生成子节点并插入到树 void CreateNInsertChildrenWithHierarchy(void); //根据父节点序号添加所有子节点 void AddChildrenWithHierarchy(int iParent); //通过层级关系获取下一个,上一个,孩子,父亲 int hSiblingNext(int icurrent); int hSiblinePrev(int icurrent); int hChild(int icurrent); int hParent(int icurrent); //合并相邻多边形,生成新曲线,存入dstcurves int CombineAdjacentPolygons(list& scrlst, float rootValue, vector& dstcurves); //获取相邻的组,从scrVec取出放入dstgroups,返回组的个数 如无相邻多边形,则独自存入dstgroups int SelectAdjacentPolygons(list& scrlst, vector >& dstgroups); //查找scrlst中所有与pscr相邻的曲线,从scrlst中移除,存入dstpgns,返回查找到的数量 int SelectAdjacentPolygons(CMyCurve* pscr, list& scrlst, vector& dstpgns); //合并相邻多边形,取与上级圈闭接近的z值 int CreateUnitedPolgons(vector< vector >& groups, float rootValue, vector& dstcurves); //合并相邻多边形,取与上级圈闭接近的z值 int CreateUnitedPolgons(vector& group, float rootValue, vector& dstcurves); //输入的变量 不作改动 CMyCurve* m_rootCurve; vector m_childCurves; vector m_nodeVec; CPgnTree m_tree; double m_minArea; //最小圈闭面积 //子节点层级关系 配合opencv用, //vector中有四个元素 表示 0、下一个条,1、前一条,2、孩子 3、父亲 vector< vector > m_hierarchy; }; }; using namespace GObjects; //合并多个不相交多边形为一个,返回合并后的多边形 isInsideFunc表示p2是否位于p1内部的回调函数 AFX_EXT_API CMyCurve* CombinePolygons(vector& polygons, function insideFunPtr = nullptr); //只合并有包含关系的多边形,返回合并后的多边形数组 AFX_EXT_API void CombinePolygons(vector& polygons, vector& polygonsOut, function insideFunPtr = nullptr); //由构建好的多边形树生成一个多边形 AFX_EXT_API CMyCurve* CombinePolygons(vector& pgnTrees);