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.

250 lines
8.3 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.

/**************************************************************************************
文 件 名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 <set>
#include <map>
#include <functional>
namespace GObjects
{
//class CPolygonTree;
class AFX_EXT_CLASS CCon2Pgn : protected CCurveGraph
{
public:
CCon2Pgn(void);
virtual ~CCon2Pgn(void);
void ClearAll(void);
void SetContours(vector<CMyCurve*>& vec);
void SetFlts(vector<CMyCurve*>& 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<CMyCurve*>& 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<PT3Node*>& lstNodes);
//构建以每个开放等值线多边形为根,闭合等值线为结点的树,若无子结点 直接添加到输出容器中
// m_bCheckZ在此函数进行控制
void TraceOutputPolygons(void);
void EnableCheckZ(bool b) { m_bCheckZ = b; }
//members
private:
//输入的成员变量
double m_dext;
CMyCurve* m_pBorder;
vector<CMyCurve*> m_contours; //输入等值线 外部指针
vector<CMyCurve*> m_bd_faults; //输入的边界地址和断层 外部指针 第一个为边界
//最终输出的多边形
vector<CMyCurve*> m_dstPolygons;
//构建闭合多边形的树状图并输出多边形 ww 2019.4.16
void TraceOutputCircles(list<CMyCurve*>& 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<CMyCurve*>& srcCurves);
private:
set<STurning> m_tracedTurnings; // tmp 记录已经追踪到的交叉点和相连结点的线段
//中间变量
private:
//计算出的中间成员变量
vector<CMyCurve*> m_openContPolygons; //开放等值线生成的闭合多边形
vector<int> m_circleIndexes; //闭合等值线序号
map<int, list<int> > m_mapFltNodes; //存储每一根断层上所有的结点序号, 按照断线桩号进行排列
vector<GBase::CRect8> m_rectFlts; //所有断层所在矩形
//set<CMyCurve*> m_fltPolygons; //由断层追踪出来的多边形
//等值线最大值,最小值和间距
double m_maxVal;
double m_minVal;
double m_conStep;
const double m_dFLTZ; //缺省断线和边界z值
bool m_bCheckZ; //是否检查Z值的有效性
set<PT3Node*> m_borderCxNodes; //记录边界上的交叉点
set<CMyCurve*> m_borderPolygons; //存储至少一边在边界上的多边形
bool m_bBorderTracing; //是否在追踪边界
};
//多边形树中一个结点
typedef TTreeNode<CMyCurve*> CPgnNode;
typedef TMultiTree<CMyCurve*> CPgnTree;
//闭合多边形树该树第一级为一系列PolygonTreeNod根节点 每个nod包含0个或多个根节点
class AFX_EXT_CLASS CPolygonTree
{
public:
CPolygonTree();
~CPolygonTree();
void Clear();
void SetRootCurve(CMyCurve* pRootCurve);
CMyCurve* GetRootCurve(void);
void SetChildCurves(vector<CMyCurve*>& childCurves);
void AddChildCurve(CMyCurve* pChild);
//根据多边形包含关系生成树
void BuildTree(void);
//根据子曲线层级关系生成树 minArea为过滤面积
bool BuildTreeWithHierarchy(vector< vector<int> >& hierarchy, double minArea = -100);
//设置最小过滤面积
void SetFilterArea(double area) { m_minArea = area; }
//生成多个多边形
void CreatePolygons(void);
//输出的环状圈闭 析构会自动删除
vector<CMyCurve*> 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<CMyCurve*>& 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<CMyCurve*>& scrlst, float rootValue, vector<CMyCurve*>& dstcurves);
//获取相邻的组,从scrVec取出放入dstgroups,返回组的个数 如无相邻多边形则独自存入dstgroups
int SelectAdjacentPolygons(list<CMyCurve*>& scrlst, vector<vector<CMyCurve*> >& dstgroups);
//查找scrlst中所有与pscr相邻的曲线从scrlst中移除存入dstpgns,返回查找到的数量
int SelectAdjacentPolygons(CMyCurve* pscr, list<CMyCurve*>& scrlst, vector<CMyCurve*>& dstpgns);
//合并相邻多边形取与上级圈闭接近的z值
int CreateUnitedPolgons(vector< vector<CMyCurve*> >& groups, float rootValue, vector<CMyCurve*>& dstcurves);
//合并相邻多边形取与上级圈闭接近的z值
int CreateUnitedPolgons(vector<CMyCurve*>& group, float rootValue, vector<CMyCurve*>& dstcurves);
//输入的变量 不作改动
CMyCurve* m_rootCurve;
vector<CMyCurve*> m_childCurves;
vector<CPgnNode*> m_nodeVec;
CPgnTree m_tree;
double m_minArea; //最小圈闭面积
//子节点层级关系 配合opencv用
//vector<int>中有四个元素 表示 0、下一个条1、前一条2、孩子 3、父亲
vector< vector<int> > m_hierarchy;
};
};
using namespace GObjects;
//合并多个不相交多边形为一个,返回合并后的多边形 isInsideFunc表示p2是否位于p1内部的回调函数
AFX_EXT_API CMyCurve* CombinePolygons(vector<CMyCurve*>& polygons,
function<bool(CMyCurve*, CMyCurve*)> insideFunPtr = nullptr);
//只合并有包含关系的多边形,返回合并后的多边形数组
AFX_EXT_API void CombinePolygons(vector<CMyCurve*>& polygons, vector<CMyCurve*>& polygonsOut,
function<bool(CMyCurve*, CMyCurve*)> insideFunPtr = nullptr);
//由构建好的多边形树生成一个多边形
AFX_EXT_API CMyCurve* CombinePolygons(vector<CPolygonTree*>& pgnTrees);