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.

245 lines
8.8 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.

#pragma once
#ifndef AFX_EXT_CLASS
#define AFX_EXT_CLASS Q_DECL_IMPORT
#endif
#include "Triangulation.h"
#include <list>
namespace NVoronoi
{
class CVoronoi;
//单个Voronoi图元
class AFX_EXT_CLASS CVoronoiUnit
{
public:
CVoronoiUnit(CVoronoi* pParent);
/** @brief判断该图元是否闭合 */
bool IsClosed();
/** @brief 添加边界返回1表示添加成功 */
bool AddBorder(CMyCurve& border);
/** @brief 添加断层,即由断层进行切割*/
bool ClipWithFlts(vector<CMyCurve*>* pFlts, vector<CRect8>* pRects = 0);
//获取多边形曲线
bool GetPolygon(CMyCurve& curve);
//清除不含中心点的多边形曲线
void EraseOtherPgns(void);
list<CMyCurve*>& GetOtherPgns(void);
int npt; //相关中心点序号
CPoint3D* ppt; //相关中心点指针
list<CPoint3D> m_nodPoints; //包含中心点的多边形
list<CMyCurve*> m_otherPgns; //不含中心点的多边形曲线
private:
/** @brief 找到中心点最小包围曲线将点存入ptlist,如果存在其他不含井点的多边形存入otherpgns*/
bool MinClosedCurve(CMyCurve& nodCur, CMyCurve& border,CPointList& ptlist, list<CMyCurve*>& otherPgns);
//父龟背图
CVoronoi* m_pParent;
};
//vorono多边形
class CVoronoiPolygon
{
public:
CVoronoiPolygon();
~CVoronoiPolygon();
int GetWell(void){return m_iWellPt; }
bool ContainWell(void) {return m_bWellInside;}
CMyCurve* GetPolygon(void) {return m_pPolygon; }
//判断两个多边形是否相邻
bool IsAdjacent(CVoronoiPolygon* pOther);
int m_iWellPt; //相关井点序号
bool m_bWellInside; // 是否包含井点
CMyCurve* m_pPolygon;
};
class AFX_EXT_CLASS CVoronoi : public CTriangulation
{
public:
CVoronoi(void);
virtual ~CVoronoi(void);
public:
/** @brief 设置相关的边界曲线工区边界、断层等pFlt为断层 pFltRects为断层对应矩形范围 */
int InitBoundary(CMyCurve* border = NULL, vector<CMyCurve*>* pFlts = 0, vector<CRect8>* pFltRects = 0);
/** @brief 生成Voronoi图获得生成的曲线元素 */
int CreateVoronoiMap(TPtrList& curveVoronoiList);
/** @brief 读取2D散点数据 */
virtual int ReadPoints(vector<double>& X, vector<double>& Y);
virtual int ReadPoints(int num, double* X, double* Y);
//标记需要图元劈分的中心点(井点)序号
void SetMarkedPoints(vector<int>& markVec);
//拆分所有标记龟背图元Polygon到相邻图元Polygon中
void SplitMarkedUnits(void);
//由断层分割多个voronoi单元 分离出的部分由相邻单元瓜分,并更新 返回分割掉的原始vunit个数
int SplitVUnitWithFlts(void);
//由断层分割龟背单元pScrVUnit生成多个voronoi多边形存入dstVUnits若断层未分割则v unit边界生成多边形
bool SplitVUnitWithFlts(CVoronoiUnit* pScrVUnit,list<CVoronoiPolygon*>& dstVPgns,
vector<CMyCurve*>* pFlts);
//由每口井的最大区域ctCurs,序号与点序号一一对应重新分配m_vPolygons & m_VUnitList
//用于单晶储量运算
void ReassignWithConstraintRects( double width, double height );
//由给定的若干v多边形重新生成局部龟背图
/** @brief 清空类*/
virtual void ClearAll();
/** @brief 清空类成员*/
void ClearVoronoi();
//获取相邻多边形的组合边界 返回个数
int CreateUnitedBoundaries( vector<CMyCurve*>& pgns, vector<CMyCurve*>& borders );
////////////////////////////////////////////////////////////////////////
//图件生成之后的调用函数
//
//获取Voronoi单元曲线
int GetVUnitCurves(vector<CMyCurve*>& curs);
//获取V多边形曲线
int GetVPolygonCurves(vector<CMyCurve*>& curs);
//获取水井劈分线曲线
int GetMWSplitterCurves(vector<CMyCurve*>& curs);
/** @brief 获得生成的所有图元多边形curveVoronoiList存放生成的曲线(CCurveEx)结果*/
int GetUnitCurve(TPtrList& curveVoronoiList);
/** @brief 获得生成的Voronoi图元多边形*/
int GetUnitCurve(int nIndex, CMyCurve& pCurve);
/** @brief 获得生成的Voronoi图的区域线个数*/
int GetUnitCount() { return (int)m_VUnitList.size(); }
/** @brief 返回voronoi单元*/
CVoronoiUnit* GetUnit(int index);
/** @brief 将Voronoi图写入文件*/
void Write(char* filename);
/** @brief 由边界条件生成Voronoi图*/
virtual int Create();
//查找位于断层内部的井点
void FindWellInFlts(void);
list<VSegment>& GetSplitterSegments(void);
private:
//拆分指定的voronoi图元到相邻图元中 idx为中心点序号
void SplitMarkedUnit(int wellIndex);
//dest合并subject相邻部分
void MergeAdjacentPart(CVoronoiPolygon* pSubjectUnit, CVoronoiPolygon* pDestUnit);
/** @brief 求取两结点中点*/
bool MidPoint(int npt1, int npt2,CPoint3D& mpt);
/** @brief 求取两结点中点*/
bool MidPoint(CPoint3D& pt1, CPoint3D& pt2,CPoint3D& mpt);
/** @brief 由边界选择数据点,删除边界外的数据点*/
void SelectPointsByBorder();
/** @brief 生成单个龟背图元*/
bool CreateVoronoiUnit(int npt, int nTri, CVoronoiUnit& vunit);
/** @brief 单方向追踪nTri相邻三角形中的Voronoi结点,addMode == 0为尾部添加点1 为头部添加 */
virtual int DirectionalTrace(int& nTri, int& npt1, int& npt2, set<int>& FDTriNos,list<CPoint3D>& nodlist, int addMode = 0);
/**@brief 准备追踪,确定首点 m_LastPoint*/
int PrepareTrace(int nTri, int npt1, int bot0,int bot1,list<CPoint3D>& nodlist, int addMode);
/**@brief 单方向追踪到边界 进行结束处理*/
int EndDirectionalTrace(int nTri, int nTop, int nBottom,list<CPoint3D>& nodlist, int addMode);
/** @brief 追踪ntri三角形中的Voronoi结点,addMode == 0为尾部添加点1 为头部添加 */
int GetVNodePoint(int nTri, int npt1, int npt2, int npt3,list<CPoint3D>& nodlist, int addMode );
/** @brief 曲线延伸到边界,求交点桩号*/
bool ExtendToBorder(list<CPoint3D>& nodlist, double& l0 , double extlen);
/** @brief 生成包络曲线 */
bool CreateEnvelopeCurve();
/** @brief生成外心点数组*/
bool CreateCirCenterPoints();
/* @brief 判断向量(x1,y1)(x3,y3)在向量(x1,y1)(x2,y2)的右侧还是左侧右侧返回0左侧返回1,线上返回2 **/
int VectorSide(double x1, double y1, double x2, double y2, double x3, double y3);
/**@brief 判断向量(pt0-pt2)在向量(pt0,pt1)的右侧还是左侧右返回0 左返回1线上返回2*/
int VectorSide(CPoint2D& pt0, CPoint2D& pt1,CPoint2D& pt2);
//生成井点序号与龟背图对应关系
void MapPointVoronoiUnit(void);
//生成井点序号与VPolygon的对应map
void MapPointVoronoiPolygon(void);
//点与多边形中的点是否有重合
bool IsAdjacent(CPoint3D& pt, list<CPoint3D>& polygon,CRect8* pRect );
//获取目标vector中所有点与polygon的邻接关系,将邻接点序号存入vecAdjacent中 返回邻接点个数
int GetAdjacentPoint(list<CPoint3D>& targetPts, list<CPoint3D>& polygon,set<CPoint3D*>& adjResult);
//将点添加到链表中
void AddPoint(list<CPoint3D>& nodlist, CPoint3D& pt, int addMode=0);
//判断坐标数组是否共线 如果是 返回true 否 返回false
bool IsCollinear(double prec);
//当井点共线时或只有一个井点时生成voronoi单元
int CreateCollinearVoronoiMap();
//当井点共线时生成voronoi单元curveVoronoiList存放生成的曲线(CCurveEx)结果
int CreateCollinearVoronoiMap(TPtrList& curveVoronoiList);
//获取V多边形相邻的多边形相同井点的多边形除外,bCompareAllPgns= true 与图中所有井点区域比较false= 只与关联井点比较
int GetAdjacentPolygons(CVoronoiPolygon* pscrPgn, list<CVoronoiPolygon*>& dstpgns, bool bCompareAllPgns = false);
//查找相邻Voronoi单元井点
int GetNeighborWells(int iWell, vector<int>& neighborWells);
//获取相邻多边形的大边界
CMyCurve* CreateBoundary( list<CVoronoiPolygon*>& pgns );
//获取一组相邻多边形的大边界线段
void GetBoundarySegs( list<CVoronoiPolygon*>& scrPgns, list<VSegment>& dstSegs );
//获取一组相邻多边形的大边界线段
void GetBoundarySegs( vector<CMyCurve*>& scrPgns, list<VSegment>& dstSegs );
//连接两条有公共点的曲线 如公共点 返回0
CMyCurve* CreateBoundary(list<VSegment>& scrSegs);
//生成子VORONOI图
bool CreateSubVoronoi(list<CVoronoiPolygon*>& pgns, CMyCurve* pBoundary,CVoronoi& dstVrn,
std::map<int,int>& subwell2origwell,vector<CMyCurve*>* pFlts);
//由子voronoi图更新原图
void UpdateWithSubVoronoi(CVoronoi& dstVrn, std::map<int,int>& subwell2origwell);
//由vpolygon更新vunit
void UpdateVUnitWithVPolygon(CVoronoiUnit* pDstUnit, CVoronoiPolygon* pScrPolygon);
//清空vpolygons
void ClearVPolygons(void);
//根据坐标获取井点序号
int GetWellIndex(double x, double y);
//两线段减去相同部分,得到不同部分的线段个数,若无相交(或仅有一点相交) 返回0
int SubtractSegment(VSegment& v1, VSegment& v2, vector<VSegment>& dstSegs);
//设置在断层中的井点序号
set<int>& GetWellInFlt(void);
//获取矩形四边 etdLen 为每条边延伸长度,缺省-1
void GetRectLines(double x0, double y0, double w, double h,CMyCurve* lines, double etdLen = -0.1);
private:
/** @brief 三角形外心*/
vector<CPoint3D*> m_CCPoints;
/** @brief 所有龟背图元容器*/
vector<CVoronoiUnit*> m_VUnitList;
/** @brief voronoi单元被断层分割后的多边形*/
list<CVoronoiPolygon*> m_vPolygons;
typedef list<CVoronoiPolygon*>::iterator VPITER;
/** @brief Voronoi图边界线 */
CMyCurve m_Border;
/** @brief 网格包络线*/
CMyCurve m_OutlineCurve;
vector<CMyCurve*>* m_pFlts;
vector<CRect8> m_fltRects;
//标记中心点劈分///////////////////////
CPoint3D m_LastPoint;
set<int> m_markedPoints; //标记的井点序号
map<int, int> m_mapPtVUnit; //点序号与voronoi unit序号的map
map<int,CVoronoiPolygon*> m_mapPtVPng; //点序号与对应VPolygon指针的map
set<int> m_wellinflt; //位于断层内部的井点序号 用于断层分割
CSize8* m_pConstrainSize; //用于分割的矩形长宽
list<VSegment> m_splitterSegments; //分割水井(标记井)的线段
};
}; //NTriangle