/************************************************************ * @file FNet.h 含逆断层曲面网格化类 * @version 1.0 * @date 2011-2012 ************************************************************/ #pragma once #include #include "Fpoints.h" #include "weightdf.h" #include "Fpointno.h" #include "FlineLink.h" /** 网格插值模式*/ enum FUN_INTER_MODE { REPLACE , UNCHANGE, ACCUMULATE, MINUS, AVERAGE, MAXIMUM, MINIMUM }; /************************************************************************ C F N E T 逆断层网格化程序 I.网格数据结构(CFunction2D格式): ①在背景网格上构建连接线(CFLineLink),连接线由数据节点(CFPointLink) 指针构成; ②每根垂直连接线都分布在网格线上,包括盘号,起始点(i,j),起始结点指针数组和结点个数等。 在网格平面上,逆断层外部的连接线盘号都为0,逆断层内部为相应盘号。如图 |0 | ----|-|------------- 逆断层 -10 -10 | |10 逆断层 ----|-|------------- 逆断层 10 | | | | 0 而正断层不会产生新连接线 |0 | ----|-------------- 正断层10 | 正断层 ----|-------------- 正断层10 | | | | 0 II.网格化步骤: ① 调用Create(int m, int n, double x0, double y0, double dx, double dy, CPtrList& outline_list,CPtrList& flt_list)函数, 由轮廓线和断层线生成total个节点类对象,和m个CFLineLink线list; ② 设置网格化参数,精度precision, 平滑度smooth, 循环次数loopmax,loopmin等; ③ 调用Play(CPtrList& outline_list,CPtrList& flt_list,CFPoints &m_points) 通过断层和散点对构建好的网格各结点进行赋值,包括 SetLink(); 背景网格上的数据节点建立关联 SetLinkFlt(flt_list); 断层关联,由断层打断周围网格节点关联 SetLink45(); 判断各结点CFPoint是否为断层点,如果是,该点IsFal = 1 ReadPoint(m_points); 建立各个结点的pInside Initial(); 用有效结点对周围无效结点赋值 Iter(0); 对所有网格结点进行平滑,校正 ************************************************************************/ class AFX_EXT_CLASS CFNet : public CGrid { public: CFNet(void); ~CFNet(void); /** @brief 网格结点初始化,用有效结点对周围无效结点赋值*/ int Initial(void); /** @brief 构造网格,m列n行,由轮廓线和断层初始化各条数据连接线m_inline[i] */ virtual int Create(int m, int n, double x0, double y0, double dx, double dy, CPtrList& outline_list, CPtrList* pFltList); virtual int Create(int numx, int numy, double x0, double y0, double dx, double dy); /** @brief 通过断层和散点对构建好的网格各结点进行赋值 */ int Play(CFPoints &m_points, CPtrList& outline_list, CPtrList* pFltList); /** @brief 通过断层,边界和CFunction2D曲面对构建好的网格各结点进行赋值*/ int Play( CFunction2D& fun, CPtrList* pFltList = NULL, CPtrList* pOutline_list = NULL); /** @brief 由CFunction2D曲面对网格结点进行插值*/ int Fun2DInterpolation(CFunction2D& fun, FUN_INTER_MODE* pMd = NULL ); /** @brief 由空白网格结点周围已赋值结点对其进行赋值*/ int RepeatInterpolation(); /** @ 对已有网格进行一次加密 */ CFNet* Double(CFPoints &m_points, CPtrList& outline_list, CPtrList* pFltList, int IsReadPoint); /** @brief 根据指定误差对所有结点进行多次数值校正,由相关散点和周围结点计算各维度偏移量*/ int Iter(int ss); /** @对所有结点进行一次重复计算,数值校正,由相关联散点(若存在)和关联结点计算各维度偏移量*/ double IterOne(int ss); void CreateOther(int tm); int SetDC(CDC& dc); virtual void Empty();//清空 /** @brief 返回线容器m_inline[i]中盘号m_No,y方向网格序号为j的点指针,即网格位置(i,j)上盘号为m_No的结点指针*/ CFPointLink * Position(int i, int j,int m_No); /** @brief 返回网格位置(i,j)上的第一个结点*/ CFPointLink * Position(int i, int j); /** @brief 得到网格位置为(i,j)上的所有结点指针和对应盘号,当前断层挂靠的盘除外, 存在临时变量pPointIJ[]和__ValueNoIJ[]中,返回符合要求的结点个数 */ int Position1(int i, int j); /** @brief */ CFPointLink * Position2(int i, int j, int dx, int dy); int PositionLineY(int i, int j1,int j2); CFLineLink * PositionLine(int i, int j); /* @brief 网格位置为(i,j)上的pPoint结点点与四周相同盘号的结点连接 */ void SetLink(int i, int j, CFPointLink *pPoint, int m_No); /* @brief 网格结点CFPointLink之间建立初步连接关系*/ void SetLink(); /* @brief 判断各结点isFal */ void SetLink45(); /** @brief 断层关联,由断层关联或打断周围网格节点,正断层打断两侧结点连接,逆断层建立两侧结点连接。 ①对于逆断层外部的正断层,不管正断层盘号为多少,都将打断其周围盘号为0的数据节点连接 逆断层中的正断层,只有当盘号与逆断层上(或下盘)一致时,才能起到断层作用,因为逆断层内不存在0盘结点 ②处理逆断层两侧结点时, ---|-|--------逆断层-m | | t3(-m)。。结点t2,盘号m ---+-+------ 逆断层 m 。结点t1,盘号为0 | 比如盘号为m的逆断层,通过函数Position(i,j,m)和Position(i,j+1,m)判断两侧结点t1,t2,t3哪个是属于m盘的, 如图t2属于m盘,t1属于0盘,则由t2连接到其正下方点t1 */ void SetLinkFlt(CPtrList* pFltList); void SetLinkOther(); void SetLinkOther1(); /** @brief 若t1,t2都存在,将t2 连接在t1的d方向上*/ void LinkTwoPoint(CFPointLink* t1, CFPointLink* t2, int d); void GetPoint(CFPointLink * t, int& i, int& j, int& no); /* @brief 从points中读取散点数据 */ int ReadPoint(CFPoints &points); void WriteMesh(FILE* fw); void WriteMesh(CString m_output); void WriteLine(FILE *fw); void WriteLine(CString m_output); void WritePointMaxError(CString m_error); /** @brief 输出网格,CFunction2D格式*/ void Write(CFile& fw); void Write(CString m_output); /** @brief 得到结点Z值范围*/ bool GetRange(); /** @brief 将曲面写成CFunction2D格式 wcw*/ void WriteGrid(CFunction2D& fun); /** @brief 利用CFunction2D曲面对象初初化数据 wcw*/ void ReadFromGrid(CFunction2D& fun); CFPointLink* AddLineOnePoint(int i, int j, int m_no,int tm); ////////////////////////////////////////////////////////////////////////////////////////////////// _int32 total; //所有结点的数目 CFPointLink* pPoints; //结点数组 /* @brief 线容器数组,m_inline[i]表示第i列垂直网格线数组,它们根据盘号m_No区分 如 */ CList *m_inline; // |0 | // | 0 比如 // |1 | //m_inline[0] m_inline[1] CWeightDF w; int ViewStep; double weight; CFPointLink* pPointMaxError; CString m_error; int error_no; int OtherBegin; long loopmin; long loopmax; int IsCreateOther; private: int Iter(int i1,int j1,int i2,int j2,int ss,int MaxLoop); double IterOne(int i1,int j1,int i2,int j2,int ss); /** @brief 结点属性值初始化,对每一个pInside为空结点,由周围若干个pInside不为空的点赋值 */ int Initial(CFPointInside &temp); /** @brief 检查所有结点,所有pInside为NULL的结点赋网格点均值,其pInside为temp的数据指针赋空 */ int InitialEmpty(CFPointInside &temp); /** @brief另一种初始化方式,由每一个存在pInside的结点对周围若干个空pInside结点赋值 */ int Initial2(CFPointInside &temp); /** @brief 由断点线段(i1,j1)-(i2,j2)在X方向上两结点确立连接关系,逆断层相连,正断层打断 */ void SetLinkFltXRepeat(double i1, double j1, double i2, double j2,int no) ; /** @brief 由断点线段(i1,j1)-(i2,j2)在Y方向上确定盘号为no的结点连接关系,逆断层相连,正断层打断*/ void SetLinkFltYRepeat(double i1, double j1, double i2, double j2,int no) ; /** @brief 由线段(i1,j1)- (i2,j2)在X方向上打断各结点与上方盘号为0的结点的连接 */ void SetLinkFltX(double i1, double j1, double i2, double j2) ; /** @brief 打断网格位置(i,j)盘号为no的结点与正上方结点的连接关系 */ void SetLinkFltX(int i,int j, int no = 0) ; /** @brief 由线段(i1,j1)- (i2,j2)在Y方向上打断各结点与右方盘号为0的结点的连接 */ void SetLinkFltY(double i1, double j1, double i2, double j2) ; /** @打断(i,j)出盘号为no的结点与正右方结点的连接关系*/ void SetLinkFltY(int i,int j, int no = 0) ; int RepeatCount(CPtrList& flt_list); /** @brief 通过断层对m_inline[i]线容器添加和修改数据各条连接线CFLinkLink, k 为总结点数目,并且只在逆断层内部添加新线 */ void RepeatCreate(CPtrList& flt_list,int &k); void RepeatOne(CFPointNos &pn,int &k); void RepeatOne(int i,int j1,int j2,int &k,int no); void RepeatOne(int i,int j1,int j2,int &k,int no,CFLineLink *line); /** @brief 用来处理逆掩断层中的断层,如当前断层name格式为‘断层号a|断层号b1|断层b2’ 找到与断层a相交的逆断层号b1,b2,记录个数*/ void GetCrossNo(char *name); /** @判断当前断层是否与m_no盘相交,即CrossNo 中是否存在m_no*/ int IsBreak(int m_no); int * CrossNo; ///< 临时变量,记录某一断层相交的逆掩断层序号 int CrossNum; ///< 临时变量,记录某一断层相交的逆断层个数 CFPointLink** pPointIJ; ///< 临时变量,记录目标结点指针数组 CFLineLink ** pLineIJ; ///< 临时变量,记录目标线指针数组 int * __ValueNoIJ;///< 临时变量,记录目标盘号数组 public: CDC* pDC; //pDC指向栈 const double DEFAULT_UPPER_LIMIT_VALUE; //默认属性值上限 }; void AFX_EXT_CLASS GetCoefficient(); void AFX_EXT_CLASS GetCoefficient1();