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.

240 lines
8.5 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.

/************************************************************
* @file FNet.h 含逆断层曲面网格化类
* @version 1.0
* @date 2011-2012
************************************************************/
#pragma once
#include <afxtempl.h>
#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_Noy方向网格序号为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的逆断层通过函数Positioni,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<CFLineLink *,CFLineLink *> *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相交的逆断层号b1b2记录个数*/
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();