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.

925 lines
35 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.

/**************************************************************************************
文 件 名Bend.h
主要功能:
多井地层对比层连接类,包含连层与断层的信息,以及断层切割算法以及是否封堵等功能
主要函数列表:
1 virtual void CreateBendLines(); 创建连层线
2 void CreateBendLine(BOOL bTop); 创建上下层位线
3 virtual void CreateBendFills(); 创建连层填充区域
4 void CreateBendLithoBreak(); 创建岩性尖灭线
5 断层切割层位,
BOOL FaultCut(CPointArr* ptsIn, CPointArr* ptsOut,BOOL bTop, double dLeft=0.0, double dRight=0.0, BOOL bBreak=FALSE,BOOL bCross=TRUE);
参数说明ptsIn为传入点集ptsOut为传出点集bTop判断是否为上层位线 bBreak判断是否为岩性尖灭bCorsss是否求断层与bend的左右交点
6 void FaultPlug(); //断层封堵流体、岩性
修改历史记录:
简述增加了CCurveEx m_curveTopNew; 上层位线
CCurveEx m_curveBotNew; 下层位线
CPointArr m_ptArrCurveTop; 上层位线有尖灭时的控制点数组
CPointArr m_ptArrCurveBot; 下层位线有尖灭时的控制点数组
四个变量为了适应新版pcg上下层位线可以选中并且可以拖动控制点调整上下层位线趋势。
简述:增加变量
m_curveBreakLithoOld 存放岩性尖灭线原始控制点坐标
m_ptArrInsertTopNew; //上层位线与断层相交点变化后的信息(做岩性封堵时使用)
m_ptArrInsertBotNew; //下层位线与断层相交点变化后的信息(做岩性封堵时使用)
m_bBreakLitho; //旧版岩性尖灭时修改岩性用
m_SelectCurveMode;////当前选中的对象(上、下层位线,岩性尖灭折线)
CurveType //断层切割时区分上线层位线和岩性尖灭线
**************************************************************************************/
#ifndef BEND_H
#define BEND_H
#pragma once
#include "WellPoleLib/WellBaseObj.h"
#include "WellPoleLib/InTrackDepthSegment.h"
#include "FaultObj.h"
//层位控制点
struct BendControlStuct
{
int level;
double X;
double Y;
};
//断点的信息
struct FaultCrossStuct
{
BOOL bCross; //是否相交
int nUCross; //左交点序号,(nUCross,nDCross ;与层位线相交时,记录了是那两个层位线点(两层位线点在层位线中的ID号)与断层线的相交) (当与断层有多个交点时,会记录最后一个交点的信息)
int nDCross; //右交点序号
dfPoint point; //
dfPoint firstPoint; //交点当与断层有多个交点时,这个记录第一个交点的信息。
int nFirstUCross;
int nFirstDCross;
public:
FaultCrossStuct()
{
bCross = FALSE;
nUCross = -1;
nDCross = -1;
nFirstUCross = -1;
nFirstDCross = -1;
}
void Serialize(CArchive& ar, const short &ver)
{
if(ar.IsStoring())
{
ar << bCross;
ar << nUCross;
ar << nDCross;
ar << point.x0; ar << point.y0;
ar << nFirstUCross;
ar << nFirstDCross;
ar << firstPoint.x0; ar << firstPoint.y0;
}
else
{
ar >> bCross;
ar >> nUCross;
ar >> nDCross;
ar >> point.x0;
ar >> point.y0;
ar >> nFirstUCross;
ar >> nFirstDCross;
ar >> firstPoint.x0; ar >> firstPoint.y0;
}
}
FaultCrossStuct& operator=(const FaultCrossStuct& other)
{
bCross = other.bCross;
nUCross = other.nUCross;
nDCross = other.nDCross;
point.x0 = other.point.x0;
point.y0 = other.point.y0;
nFirstUCross = other.nFirstUCross;
nFirstDCross = other.nFirstDCross;
firstPoint.x0 = other.firstPoint.x0;
firstPoint.y0 = other.firstPoint.y0;
return *this;
}
};
//断点的距离
struct FaultThrowStuct
{
//int nID; //断层ID
CString faultName;
double fUThrow; //左距离
double fDThrow; //右距离
public:
FaultThrowStuct()
{
fUThrow = 0;
fDThrow = 0;
}
void Serialize(CArchive& ar, const short &ver)
{
if(ar.IsStoring())
{
//ar << nID;
ar << faultName;
ar << fUThrow;
ar << fDThrow;
}
else
{
//ar >> nID;
ar >> faultName;
ar >> fUThrow;
ar >> fDThrow;
}
}
};
//层上的断层、断点
struct FaultOnBendStruct
{
CFaultObj* pFault; //断层指针
//int faultID; //断层ID
CString faultName;
FaultThrowStuct faultThrow; //距离
FaultCrossStuct faultUCross;//上层位线交点信息
FaultCrossStuct faultDCross;//下层位线交点信息
//FaultCrossStuct faultBreakCross; //尖灭线交点信息
CPoint2D faultBandPt[2]; //记录了断层和层位相交计算时层位线与断层线的左右两个交点,起临时变量的作用。
int fBanPtId; //临时变量,用来计数上述两个点的赋值情况。
public:
FaultOnBendStruct()
{
pFault = NULL;
// faultID = -1;
fBanPtId = 0;
}
FaultOnBendStruct& operator=(const FaultOnBendStruct& other)
{
pFault = other.pFault;
//faultID = other.faultID;
faultThrow = other.faultThrow;
faultUCross = other.faultUCross;
faultDCross = other.faultDCross;
faultBandPt[0] = other.faultBandPt[0];
faultBandPt[1] = other.faultBandPt[1];
faultName = other.faultName;
fBanPtId = fBanPtId;
return *this;
}
void AddFaultBandPt(double x,double y)
{
if(fBanPtId<2)
{
faultBandPt[fBanPtId].x0 = x;
faultBandPt[fBanPtId].y0 = y;
fBanPtId++;
}
}
void Serialize(CArchive& ar, const short &ver)
{
if(ar.IsStoring())
{
//ar << pFault->GetId();
ar << faultName;
}
else
{
//ar >> faultID;
ar >> faultName;
}
faultThrow.Serialize(ar, ver);
faultUCross.Serialize(ar, ver);
faultDCross.Serialize(ar, ver);
//faultBreakCross.Serialize(ar, ver);
}
};
/*
层位线被断层切割的实现思路:
1、先将层位的首尾点与所有断层线相交记录相交的断层线并按照从左到右排序断层线。
2、从左侧依次插入断层线并根据这个断层的左右断距调整被切开的左侧右侧层位线片段。由于是从左侧依次插入被切割后的左侧层位片段会有可能夹在两个断层之间右侧的层位片段左边起始会是本次断层切割点。
3、由于层位线有多种样式存在例如字样式因此层位线被断层线切割后会有多个片段存在。除去头尾片段这类层位线片段的前后都与一条断层线相交.被切割的层位分段会分布在断层线的左右两侧,
后面新增的断层线都只会与这次断层线切割后右侧片段相交。
3、本组件中连层层位线及朝右尖灭的层线中的点数据都是从左到右存放朝左尖灭的层线其点数据是从右到左。从代码中则都是从m_pLeftLayer出发
为了一致的处理断层与层位的交叉问题,对于朝左尖灭的层位,则先将其中的点都反向存放,使用时注意要反向组织层位线片段点。
4、_LayerLineFragment结构记录层位被断层切割后的层位片段,这个片段包括两个部分,层位线片段+本次切割断层线的交点数据(断层线两侧的偏移层位点及交点).
每次切割后的片段个数是断层交点个数加1.交点的信息记录在前一段片段中。
由于复杂样式层位线的存在因此每次断层线与层位线交点ID从层位线的点数组看是ID增长的但层位片段有可能是左到右或右到左这些层位片段按照被切割的顺序存放。
*/
typedef struct _LayerLineFragment
{//层位线片段
CFaultObj *pFaultPre; //层位线片段头部切割断层线
dfPoint preFaultPt;////是断层线pFaultPre与层位线的交点的本片断端的偏移点(与上一个片段中nextPt2相同)
CString strLeftFault;
CFaultObj *pFaultNext; //层位线片段尾部切割断层线
CString strRightFault;
std::vector<dfPoint> linePts;
CCurveEx lineCurve;
//BOOL bLayerLine; //表示是层位还是断层片段
BOOL bOnRight; //如果一个层位被断层多次切割,记录这个层位片段线是否在断层的右侧(如之字形态的层位线,会被多次切割,这时本片段线的左右两侧断层线是一条),右侧的层位会被下条断层切割
/*下面四变量都是层位右侧的断层线的相关点。
层位线与断层切割按照从左到右的处理原则,如果层位线被切割,则一定是右侧被切断,这时与右侧断层相关的信息都是记录在本层位线片段中。
层位线点数组的id按照从左到右的顺序递增不管层位线朝左或朝右为了能期间的断层线点也需要按照顺序进行负值如果层位线从左到右则nextFaultPt记录左偏移点nextFaultPt2记录右偏移点
如果层位线从右到左则nextFaultPt记录右偏移点nextFaultPt2记录左偏移点
这样最后生成层位线条时,直接按照顺序使用即可
*/
dfPoint nextFaultPt; //是断层线pFaultRight与层位线的交点的左偏移点
dfPoint nextFaultPt2; //是断层线pFaultRight与层位线的交点右偏移点(目前将这个点存放本片段中,导致下一个片段使用时需要不停的找前一个片段,效率较低.20250420)
dfPoint fbintectPt; //交点
std::vector<dfPoint> faultPts; //保存断层线上价值左右断层线间距间的点
std::vector<dfPoint> leftExtentPts; //绘制油水分界线时,划分不同的填充区域使用。
std::vector<dfPoint> rightExtentPts;
BOOL bShow;
static int s_count;
_LayerLineFragment()
{
pFaultPre = NULL;
pFaultNext = NULL;
bOnRight = FALSE;
bShow = TRUE;
bAddFirstPoint = FALSE;
// _LayerLineFragment::s_count++;
// TRACE(" layerline count=%d \r\n", _LayerLineFragment::s_count);
}
~_LayerLineFragment()
{
// s_count--;
// TRACE(" ~~~~ layerline count=%d \r\n", _LayerLineFragment::s_count);
}
_LayerLineFragment& operator=(const _LayerLineFragment& other)
{
pFaultPre = other.pFaultPre;
preFaultPt = other.preFaultPt;
strLeftFault = other.strLeftFault;
pFaultNext = other.pFaultNext;
strRightFault = other.strRightFault;
linePts.assign(other.linePts.begin(), other.linePts.end());
lineCurve = other.lineCurve;
bOnRight = other.bOnRight;
nextFaultPt = other.nextFaultPt;
nextFaultPt2 = other.nextFaultPt2;
fbintectPt = other.fbintectPt; //交点
faultPts.assign(other.faultPts.begin(), other.faultPts.end());
leftExtentPts.assign(other.leftExtentPts.begin(), other.leftExtentPts.end());
rightExtentPts.assign(other.rightExtentPts.begin(), other.rightExtentPts.end());
bShow = other.bShow;
bAddFirstPoint = other.bAddFirstPoint;
return *this;
}
BOOL bAddFirstPoint; //加点的临时变量
public:
void Serialize(CArchive& ar, const short &ver)
{
if (ar.IsStoring())
{
if (pFaultPre != NULL)
strLeftFault = pFaultPre->m_strName;
if (pFaultNext != NULL)
strRightFault = pFaultNext->m_strName;
ar << strLeftFault << strRightFault;
ar << bOnRight;
int num = linePts.size();
ar << num;
for (int ii = 0; ii < num; ii++)
{
ar << linePts[ii].x0 << linePts[ii].y0;
}
ar << preFaultPt.x0 << preFaultPt.y0;
ar << nextFaultPt.x0 << nextFaultPt.y0;
ar << nextFaultPt2.x0 << nextFaultPt2.y0;
ar << fbintectPt.x0 << fbintectPt.y0;
ar << bShow;
num = leftExtentPts.size();
ar << num;
for (int ii = 0; ii < num; ii++)
{
ar << leftExtentPts[ii].x0 << leftExtentPts[ii].y0;
}
num = rightExtentPts.size();
ar << num;
for (int ii = 0; ii < num; ii++)
{
ar << rightExtentPts[ii].x0 << rightExtentPts[ii].y0;
}
}
else
{
ar >> strLeftFault >> strRightFault;
ar >> bOnRight;
int num;
ar >> num;
dfPoint tpt;
for (int ii = 0; ii < num; ii++)
{
ar >> tpt.x0 >> tpt.y0;
linePts.push_back(tpt);
}
ar >> preFaultPt.x0 >> preFaultPt.y0;
ar >> nextFaultPt.x0 >> nextFaultPt.y0;
ar >> nextFaultPt2.x0 >> nextFaultPt2.y0;
ar >> fbintectPt.x0 >> fbintectPt.y0;
ar >> bShow;
ar >> num;
for (int ii = 0; ii < num; ii++)
{
ar >> tpt.x0 >> tpt.y0;
leftExtentPts.push_back(tpt);
}
ar >> num;
for (int ii = 0; ii < num; ii++)
{
ar >> tpt.x0 >> tpt.y0;
rightExtentPts.push_back(tpt);
}
}
lineCurve.Serialize(ar, ver);
}
void GetLeftRightPoint(CPoint2D& leftPt, CPoint2D& rightPt)
{
rightPt.x0 = leftPt.x0 = linePts[0].x0; rightPt.y0 = leftPt.y0 = linePts[0].y0;
if (lineCurve.num == 0)
{
for (int ii = 0; ii < linePts.size(); ii++)
{
if (linePts[ii].x0 < leftPt.x0)
{
leftPt.x0 = linePts[ii].x0;
leftPt.y0 = linePts[ii].y0;
}
if (linePts[ii].x0 > rightPt.x0)
{
rightPt.x0 = linePts[ii].x0;
rightPt.y0 = linePts[ii].y0;
}
}
}
else
{
for (int ii = 0; ii < lineCurve.num; ii++)
{
if (lineCurve.x[ii] < leftPt.x0)
{
leftPt.x0 = lineCurve.x[ii];
leftPt.y0 = lineCurve.y[ii];
}
if (lineCurve.x[ii] > rightPt.x0)
{
rightPt.x0 = lineCurve.x[ii];
rightPt.y0 = lineCurve.y[ii];
}
}
}
}
} LAYERLINEFRAGMENT;
/* 层位区域片段与岩性分界线的切割方式:
将岩性分界线与左侧连层形成封闭拾取多边形并切割区域片段多边形,
将切割后生成的多边形保存在leftFillCurves中。渲染时区域片段整体多边形使用右侧充填leftFillCurves使用左侧充填
*/
typedef struct _StratumFragment
{//层位区域片段
CFaultObj *pFaultLeft;
CString strLeftFault;
CFaultObj *pFaultRight;
CString strRightFault;
CCurveEx fillCurve;//区域片段的填充
std::vector<CCurveEx*> leftFillCurves; //左侧填充区域
std::vector<LAYERLINEFRAGMENT*> topLayerLines; //bend中层位线的片段指针生成填充区域时用一下算是临时变量保存时不需要使用。
std::vector<LAYERLINEFRAGMENT*> botLayerLines; //bend中层位线的片段指针。
int fillType;// 0=表示默认的地层片段,
BOOL bShow;
_StratumFragment()
{
pFaultLeft = NULL;
pFaultRight = NULL;
fillType = 0;
bShow = TRUE;
}
public:
void MakeFillCurve(CBendObj* pBend);
void Serialize(CArchive& ar, const short &ver);
~_StratumFragment()
{
ClearLeftFillCurves();
}
void ClearLeftFillCurves();
_StratumFragment& operator=(_StratumFragment& other)
{
pFaultLeft = other.pFaultLeft;
strLeftFault = other.strLeftFault;
pFaultRight = other.pFaultRight;
strRightFault = other.strRightFault;
fillCurve = other.fillCurve;
ClearLeftFillCurves();
for (int i = 0; i < other.leftFillCurves.size(); i++)
{
CCurveEx* pCurve = new CCurveEx;
*pCurve = *other.leftFillCurves[i];
leftFillCurves.push_back(pCurve);
}
fillType = other.fillType;
bShow = other.bShow;
//bend中层位线的片段指针只是记录自己需要使用的层位线指针(如果是bend进行=号操作时需要记录自己所属的bend内的片段不是other的)
//topLayerLines.clear();
//topLayerLines.assign(other.topLayerLines.begin(), other.topLayerLines.end());
//botLayerLines.clear();
//botLayerLines.assign(other.botLayerLines.begin(), other.botLayerLines.end());
return *this;
}
protected:
void getLinesPoints(CBendObj* pBend, std::vector<LAYERLINEFRAGMENT*>&fraglayerLines, std::vector<LAYERLINEFRAGMENT*>&bendlayerLines, std::vector<dfPoint>& curvePts);
} STRATUMFRAGMENT;
//控制点偏移量
struct ControlYOffSet
{
double OneOffSet; /// 1/3处控制点偏移量
double TwoOffSet; /// 2/3处控制点偏移量
double OneX; // 这两个X的数据在ResForm里有使用双狐的暂时没有用到双狐狸软件中将控制点的x位置定死了
double TwoX; //
};
typedef CArray<BendControlStuct, BendControlStuct> CONTROLPOINTARR; //控制点结构数组
typedef CArray<FaultThrowStuct, FaultThrowStuct> FAULTCONTROLARR; //断点距离结构数组
typedef CArray<FaultOnBendStruct, FaultOnBendStruct> FAULTONBENDARR; //断层结构数组
typedef CArray<CCurveEx*, CCurveEx*> CURVEARR; //曲线数组
typedef CArray<ControlYOffSet, ControlYOffSet> CONTROLOFFSETARR; //控制点y值偏移量数组
class CFaultObj;
class AFX_EXT_CLASS CBendObj : public CWellBaseObj
{
public:
CBendObj(void);
~CBendObj(void);
public:
void SetBendType(EBendType type) { m_eBendType = type; }
EBendType GetBendType() { return m_eBendType; }
CLONE_WELLOBJECT(CBendObj)
CBendObj& operator=( CBendObj& other);
public:
std::vector<LAYERLINEFRAGMENT*> m_TopLayLineFragments;//其中的层位线片段都是从左到右
std::vector<LAYERLINEFRAGMENT*> m_BotLayLineFragments; //其中的层位线片段都是从左到右,即使尖灭朝左也是如此
std::vector<STRATUMFRAGMENT*> m_StratumFragments; //层位片段,从左到右排列
CCurveEx m_ContolLine; //测试用
CCurveEx m_ControlPtLine; //测试用
CCurveEx m_TopCtrlPtB; //测试用
CCurveEx m_BotCtrlPtB; //测试用
//CCurveEx m_ControlBezierLine;
GDFLOGPENEXT m_penTop; //连层顶边线画笔
GDFLOGPENEXT m_penBottom; //连层底边线画笔
CString m_LeftLayerName; //左边连层名
CString m_RightLayerName; //右边连层名
///////////////////////////////////////////////////////////////PCG数据信息
double m_fGasBottom; //底界气
double m_fWaterTop; //顶界水
double m_fTopLithoBreakPoint; //顶界岩性断点
double m_fBottomLithoBreakPoint; //底界岩性断点
double m_fLithoBreakWidth; //岩性断点宽度
double m_fOutBendControlLevel; //外连层深度
double m_fBeginBreakPos; //尖灭开始点占井间横向距离的百分比
double m_fEndBreakPos; //尖灭结束点占井间横向距离的百分比(resform pcg中从尖灭的层位出发到尖点的横向长度占井间横向的比例)
double m_fEndBreakDepth; //尖灭结束点相对于层的纵向偏移(resform pcg中指向尖点朝向的井深度)
CString m_strLineBreakStyle; //层位线尖灭样式名
int m_nLithoBreakStyle; //岩性尖灭样式ID
int m_nWaveStyle; //不整合线样式
CONTROLPOINTARR m_ptArrControls; //连层控制点
ControlYOffSet m_ptArrControlsOffSet[2]; //层位控制点偏移量数组,(pcg读取时第一个记录了level=0的偏移量第二个记录level=1的偏移量)(在resform里可以认为第一个记录了顶部层位线的控制点第二个是底部层位线的控制点)
FAULTCONTROLARR m_faultControlsArr; //断层偏移信息,同m_faultArr个数保持一致.用来从pcg等文件中将断层偏移信息读出;鼠标动态调整偏移信息时不记录偏移信息,m_faultArr记录动态调整的偏移信息,因此保存pcg时保存m_faultArr中的偏移信息,读取时读到m_faultControlsArr(平时不使用).
/////////////////////////////////////////////////////////////////PCG数据信息
//指针对象
CWellPole* m_pWellLeft; //左连井(尖灭时使用)
CWellPole* m_pWellRight; //右连井(尖灭时使用)
CInTrackDepthSegment* m_pLayerLeft; //左连层
CInTrackDepthSegment* m_pLayerRight; //右连层(尖灭时为空)
CXy* m_pMarkBreak; //尖灭符号指针
//计算层位线使用
dfPoint m_ptBeginBreak; //尖灭点起始控制点(左右井层位的中间点,也可以看作是连层的方向线。),
dfPoint m_ptEndBreak; //尖灭点结束尖灭点
dfPoint m_ptEndBreakInteract; //上下层位线交点控制点
dfPoint m_ptLeft; //上下层位线左起点
dfPoint m_ptRight; //上下层位线的右起点
std::vector<dfPoint> m_ptArrCurveTopOldRe; //上层位线原始控制点 (从pcg文件读取的层位顶部线点放在这里,记录Resform中的相对点)
std::vector<dfPoint> m_ptArrCurveBotOldRe; //下层位线原始控制点 从pcg文件读取的层位底部线点放在这里记录Resform中的相对点
CPointArr m_ptArrCurveTopOld; //上层位线原始控制点 (从df pcg文件读取的层位顶部线点放在这里) Resform文件时记录从m_ptArrCurveTopOldRe计算后的图中坐标位置
CPointArr m_ptArrCurveBotOld; //下层位线原始控制点 从df pcg文件读取的层位底部线点放在这里Resform文件时记录从m_ptArrCurveBotOldRe计算后的图中坐标位置
CPointArr m_ptArrCurveTop; //上层位线有尖灭时的控制点数组(在resform模式下装层位线计算后的所有贝塞尔点四个点一组)
CPointArr m_ptArrCurveBot; //下层位线有尖灭时的控制点数组(在resform模式下装层位线计算后的所有贝塞尔点四个点一组)
FAULTONBENDARR m_faultArr; //断层信息数组
//绘制使用
CCurveEx m_curveTop; //上层位线
CCurveEx m_curveBot; //下层位线
CURVEARR m_curveFillArr; //填充区域集合
CCurveEx m_curveBreakLitho; //岩性或者流体分界线(控制点平滑之后)
CCurveEx m_curveBreakLithoInteract; //岩性或者流体分界线(平滑之前)
CCurveEx m_curveBreakLithoOld; //岩性或者流体分界线(原始点坐标
//临时变量
CPointArr ptArrInsertPointTemp; //与断层相交点变化后的信息
CPointArr ptArrInsertTopTemp; //上层位线与断层相交点变化后的信息(做岩性封堵时使用)
CPointArr ptArrInsertBotTemp; //下层位线与断层相交点变化后的信息(做岩性封堵时使用))
BOOL bPlug;
//连层隐藏左右侧控制变量(只有当断层油连层上下层位都相交时才能隐藏左或者右连层)
BOOL bHideBendLeft;
BOOL bHideBendRight;
BOOL bBreakLithoTemp; //旧版岩性尖灭时修改岩性用
double m_fSlope; //创建层位线时使用 斜率a y = a*x+b (如果该连层左右都有井层,可以认为是过两个井层位中间点的直线)
double m_fConstant; //创建层位线时使用 常数b y = a*x+b
CPoint2D m_pointCenter; //创建层位线时使用
CPoint2D m_pointBorder; //创建层位线时使用(尖灭时,建立控制趋势线时使用,用来作为尖灭趋势的结束点)
CPoint2D ptBreakRotateTemp; //尖灭点与上层位线的交点,为尖灭符号的旋转点
int nLeftWellID; //左连井ID
int nRightWellID; //右连井ID
int nLeftLayerIndex; //左连层索引
int nRightLayerIndex; //右连层索引
CString strLeftWellName; //左连井井名
CString strRightWellName; //右连井井名
CString m_strID; //字符串ID
std::vector<dfPoint> m_BreakLithoCtrlPoints; //ResForm中的分界线控制点
//std::vector<dfPoint> m_BreakLithoPoints; //ResForm中的分界线控制点
std::vector<LAYERLINEFRAGMENT*> m_BreakLithoLineFragments;//ResForm中的分界线片段
void SetLeftFillAuto(BOOL b);//自动填充相当于使用层位的岩性符号特性进行填充,如果设否,就是使用指定的颜色填充。
BOOL IsLeftFillAuto();
void SetRightFillAuto(BOOL b);
BOOL IsRightFillAuto();
CCurveEx* GetLeftPickCurve();
BOOL m_bNeedBreakLith;
std::vector<dfPoint> m_BendTrendLinePts; //计算出的层位中间趋势线。
GDFLOGBRUSH m_LeftBrush, m_RightBrush, m_defaultBrush;
BOOL IsLayerLineIncludePoint(BOOL btop, CPoint2D pt, double size);
protected:
enum BendFillFlags
{
BendFillLeftAuto = 0x0001,
BendFillRightAuto = 0x0002,
BendFillAllAuto = 0x0001|0x0002
};
DWORD m_nBendFillFlags;
protected:
EBendType m_eBendType; //连层类型
DWORD m_nBendFlags; //连层开关状态
DWORD m_nDrawTypeFlags; //绘制类型
DWORD m_nBendSlotType; //连层插槽类型
DWORD m_nFaultCutLineType; //断层切割线类型
// 连层类Flags
enum BendFlags
{
BendFlagWaveLine = 0x0001, // 显示不整合线
BendFlagTopWave = 0x0002, // 显示上边界不整合面
BendFlagBotWave = 0x0004 // 显示下边界不整合面
};
enum DrawTypeFlags
{
DrawTypeFlagUpLine = 0x0001, // 画上层位线
DrawTypeFlagDownLine = 0x0002, // 画下层位线
DrawTypeFlagFill = 0x0004 // 填充
};
//连层插槽类型
enum BendSlotType
{
BendSlotTypeStratiUnit = 0x0001, //地层单元
BendSlotTypeReservoirGroup = 0x0002, //油层组
BendSlotTypeSandSet = 0x0004, //砂层组
BendSlotTypeReserveUnit = 0x0008, //储量单元
BendSlotTypeResult = 0x0010, //解释分层
BendSlotTypeStandard = 0x0020, //标准层
};
// 断层切割线类型
enum FaultCutLineType
{
FaultCutLineTypeTop = 0x0001, //上层位线
FaultCutLineTypeBot = 0x0002, //下层位线
FaultCutLineTypeLitho = 0x0004, //岩性尖灭线
FaultCutTopControlLine = 0x0008 , //切割上层位线的控制点线
FaultCutBottomControlLine = 0x0010 //切割上层位线的控制点线
};
public:
//根据图元类型构建对象
static CBendObj* CreateBendObj(EBendType eType);
//克隆,虚函数
virtual void* CloneElement(void);
virtual void Serialize(CArchive& ar, const short &ver);
virtual void Draw(CXyDC* pDC);
virtual void MoveTo(CRect8& position);
virtual void MoveHandleTo(int nHandle, CPoint2D point);
virtual void MoveHandleToTop(int nHandle, CPoint2D point);
virtual void MoveHandleToBot(int nHandle, CPoint2D point);
virtual void MoveHandleToBreakLitho(int nHandle, CPoint2D point);
virtual CRect8 GetRect(void);
virtual BOOL IsInRange(CRect8& range);
virtual BOOL Intersects(const CRect8& rect, double dHandleSize);
virtual BOOL IntersectsTop(const CRect8& rect, double dHandleSize);
virtual BOOL IntersectsBot(const CRect8& rect, double dHandleSize);
virtual BOOL IntersectsBreakLitho(const CRect8& rect, double dHandleSize);
virtual CPoint2D GetHandleControl(int nHandle);
virtual CPoint2D GetHandleTop(int nHandle);
virtual CPoint2D GetHandleBot(int nHandle);
virtual CPoint2D GetHandleBreakLitho(int nHandle);
virtual int HitTest(CPoint2D point, double dHandleSize, BOOL bSelected);
virtual int HitTestControl(CPoint2D point, double dHandleSize, BOOL bSelected);
virtual int HitTestTop(CPoint2D point, double dHandleSize, BOOL bSelected);
virtual int HitTestBot(CPoint2D point, double dHandleSize, BOOL bSelected);
virtual int HitTestControl_Resform(CPoint2D point, double dHandleSize, BOOL bSelected);
virtual int HitTestTop_Resform(CPoint2D point, double dHandleSize, BOOL bSelected);
virtual int HitTestBot_Resform(CPoint2D point, double dHandleSize, BOOL bSelected);
virtual int HitTestBreakLitho(CPoint2D point, double dHandleSize, BOOL bSelected);
virtual CRect8 GetHandleRectControl(int nHandleID, double dHandleSize);
virtual CRect8 GetHandleRectTop(int nHandleID, double dHandleSize);
virtual CRect8 GetHandleRectBot(int nHandleID, double dHandleSize);
virtual CRect8 GetHandleRectBreakLitho(int nHandleID, double dHandleSize);
int GetControlCount(); //得到控制点个数
int GetBreakCount(); //得到尖灭点个数
int GetTopCount(); //得到上层位线点数
int GetBotCount(); //得到下层位线点数
int GetBreakLithoCount(); //得到岩性尖灭线点数
//创建上下层位线(老版本)
virtual void CreateBendLineForOld(BOOL bTop);
virtual void CreateBendLinesForOld(); //读老版PCG及改变尖灭样式时使用来创建连层
virtual void CreateBendLines(); //创建连层
virtual void CreateBendFills(); //创建连层填充区域
virtual void CreateBendLithoBreak(); //创建岩性尖灭线
virtual void FaultCutLines(); //断层切割连层
virtual void SmoothBendLines(); //平滑连层
virtual void GetBendXValue(double &xLeftValue,double &xRightValue);//得到连层两端的x坐标值
virtual void BendAddFault();//新添加bend层与断层的关联
//尖灭层拖动尖灭结束点时重新计算上下层位线的控制点以及连层的控制点
virtual void ComputeControlsWhenMoveEndBreak(CPoint2D point);
////////计算 fSlopefConstantpointCenterpointBorder的值
virtual void ComputeSlopeAndConstant();
//固定井间距时计算控制点;nflag=1时为当前拖动井nFlag=-1时为拖动井的前一口井
virtual void ComputeControlsWhenFixedDistance(CPoint2D pt,int nFlag=1);
///////添加或者删除连层时若存在一个层对多个连层则其余连层控制点要重新计算
virtual void ReComupteControls();
//计算新添加bend控制点所在直线的左右端点的y值
virtual void ComputeBendYValue(double &yLeftValue,double &yRightValue);
///计算尖灭层尖灭结束点横坐标距左右井的比例 尖灭层连层控制点所在直线在xRight位置的y值距右井上下的比例
virtual void ComputeBreakRatio();
// 连层隐藏左侧或者右侧连层时取断层控制点中位于上下层位线之间的控制点
virtual void GetFaultBettweenTopAndBot(CPointArr &PointArr,BOOL bHideBends,BOOL bRight = TRUE);
//手动调节断层左右断距时确保切割后的控制点不会超出断层的范围
virtual void ComputeMoveHeight(CFaultObj* pFault,double &fHeight,BOOL bLeft = TRUE);
// 写PCG时连层左右层所在道内索引排序
void SortLayerIndex(CTrackObj* pTrack);
// 计算层位拉平前控制点坐标层位拉平情况下写PCG时使用
void FlatComputeControlPointY(CPointArr &ArrTop,CPointArr &ArrBot);
//设置控制点数据
void AddControlPoints(double xLeft, double yLeft, double xRight, double yRight, double width);
///////读旧版本时把连层左右层位ID转化为索引
void TransformIDtoIndex();
/////新添加连层赋连层类型
void SetSlotType();
//获得连层线尖灭类型符号名
CString GetLineBreakStyle(int nStyle);
//获得岩性尖灭类型符号名
CString GetLithoBreakStyle(int nStyle);
//获得尖灭类型、尖灭符号曲线
void GetBreakType(int& nType, CCurveEx*& pCurve);//尖灭类型nType0上尖灭1上下尖灭2下尖灭3不对称尖灭
void GetRange(CRect8& rect);
//开关变量值
virtual void SetBendFlags(DWORD flags);
virtual void SetShowWaveLine(BOOL bFlag);
virtual void SetShowTopWave(BOOL bFlag);
virtual void SetShowBotWave(BOOL bFlag);
virtual DWORD GetBendFlags();
virtual BOOL IsShowWaveLine();
virtual BOOL IsShowTopWave();
virtual BOOL IsShowBotWave();
virtual void SetDrawTypeFlags(DWORD flags);
virtual void SetShowTopLine(BOOL bFlag);
virtual void SetShowBotLine(BOOL bFlag);
virtual void SetShowFill(BOOL bFlag);
virtual DWORD GetDrawTypeFlags();
virtual BOOL IsShowTopLine();
virtual BOOL IsShowBotLine();
virtual BOOL IsShowFill();
void SetBendSlotType(DWORD flags);
void SetSlotTypeStratiUnit(BOOL bFlag);
void SetSlotTypeReservoirGroup(BOOL bFlag);
void SetSlotTypeSandSet(BOOL bFlag);
void SetSlotTypeReservesUnit(BOOL bFlag);
void SetSlotTypeResult(BOOL bFlag);
void SetSlotTypeStandardLayer(BOOL bFlag);
DWORD GetBendSlotType();
BOOL IsSlotTypeStratiUnit();
BOOL IsSlotTypeReservoirGroup();
BOOL IsSlotTypeSandSet();
BOOL IsSlotTypeReservesUnit();
BOOL IsSlotTypeResult();
BOOL IsSlotTypeStandardLayer();
//pcg文件读写
virtual int ReadPCG_Bend(CFile &fr,const short& ver);
virtual int ReadPCG(CFile &fr,const short& ver);
virtual void WriteDML_PCG(CFile &fw,int nBaseTabNum,int xmlId =1);
virtual void WritePCG_Bend(CFile &fw, int nBaseTabNum); //旧的不用,使用 WriteDML_PCG ,20250326
/*根据层位与井的连层方式获得左右层位线的起始结束点 baseType= 0是中间控制点=1是top层位线=2是bottom层位线
尖灭层位时左点就是连接层位点,右点就是尖灭朝向的井内部控制点。*/
void GetLayerLineLeftRightBasePoint(int baseType, dfPoint& leftPoint, dfPoint& rightPoint);
//从层位线片段数组中获得整条层位线
void GetLayerLinePointsFromLayFragment(std::vector<LAYERLINEFRAGMENT*>&pLayerLines, BOOL bReverse, std::vector<dfPoint>&outPts);
void MakeLayerLineFragmentCurve(std::vector<LAYERLINEFRAGMENT*>&pLayerLines, BOOL bReverse);//生成层位线片段的曲线Curve
void SetFaultForLayerLineFragments();
void SetCutOrHideBendForAllFault();
BOOL IsIntersectFault(CFaultObj* pFault);
void SetResFormBendTopBotPoint();//将从Resform中读出的层位顶底线的相对坐标m_ptArrCurveTopOldRe,m_ptArrCurveBotOldRe计算成剖面图中的坐标m_ptArrCurveTopOldm_ptArrCurveBotOld
protected:
void SmoothBend_ResForm();
void MakeBreakLitho_ResForm();
void AddExtentPointsToLaylines(BOOL bTop, CPointArr &ptArrLeft, CPointArr &ptArrRight);//对于起始结束的层位片段是否要增加左右侧的扩展点
void SetFaultCutOrHideBendLine(CFaultObj* pLeftFault, CFaultObj* pRightFault, std::vector<LAYERLINEFRAGMENT*>&pLayerLines);//设置层位片段线数组中位于两个断层间的层位片段
//创建上下层位线(老版本)
//virtual void CreateBendLineForOld(BOOL bTop);
//计算层位线
virtual void CreateBendLine(BOOL bTop);
//virtual void CreateBendLineResForm(BOOL bTop);
// 计算岩性或者流体分界线
virtual void CreateBoundaryLine();
//上下层位线数组点
//virtual void CreateBendLinePointArr(BOOL bTop,CPointArr &ptArrControl,CPointArr &ptArrLeft,CPointArr &ptArrRight);
virtual void CreateBendLinePointArr(BOOL bTop, std::vector<dfPoint> &ptArrControl, CPointArr &ptArrLeft, CPointArr &ptArrRight);
//上下层位线curve
virtual void CreateBendLineCurve(BOOL bTop,std::vector<dfPoint> &ptArrControl,CPointArr &ptArrLeft,CPointArr &ptArrRight);
//有尖灭情况
virtual void BendLineBreak(CCurveEx* pCurve, int nBreakType, std::vector<dfPoint> &ptArrControl, CPointArr &ptArrControlOriginal, double fHLeft, double fHRight, BOOL bTop);
//求岩性尖灭线
virtual void BendLithoBreak(CString str,CPointArr &ptArrControl,CInTrackDepthSegment* pLayerThin,CInTrackDepthSegment* pLayerThick);//x为上层位线岩性尖灭点百分比,y为下层位线岩性尖灭点百分比
//virtual void BendLineBreakDeal(CPointArr &ptArrControl,CPointArr &ptArrControlOriginal,CCurveEx *pCurve,BOOL bTop,int nStyle,double fHLeft,double fHRight);//nStyle:0,上尖灭1上下尖灭或是不对称尖灭2下尖灭
virtual void BendLineBreakDeal(std::vector<dfPoint> &ptArrControl, CPointArr &ptArrControlOriginal, CCurveEx *pCurve, BOOL bTop, int nStyle, double fHLeft, double fHRight);//nStyle:0,上尖灭1上下尖灭或是不对称尖灭2下尖灭
virtual void BendLithoBreakDeal(CPointArr &ptArrControl,CPointArr &ptArrControlOriginal,CCurveEx *pCurve,double x);
//变形函数
//virtual void BreakTransform(CPointArr &ptArrControl,CPointArr &ptArrControlOriginal,CPointArr &ptArrCurve,BOOL bTop,BOOL bLith=0);//
virtual void BreakTransform(std::vector<dfPoint> &ptArrControl, CPointArr &ptArrControlOriginal, CPointArr &ptArrCurve, BOOL bTop, BOOL bLith = 0);//
//断层切割层位
BOOL FaultCut(std::vector<dfPoint>* ptsIn, CPointArr* ptsOut,DWORD nCutType,double dLeft=0.0, double dRight=0.0, BOOL bBreak=FALSE,BOOL bCross=TRUE);
//resForm方式下将传入的点线与断层进行切割并按照断距偏移点线
BOOL FaultCut_ResForm(std::vector<dfPoint>* ptsIn, CPointArr* ptsOut, DWORD nCutType, double dLeft = 0.0, double dRight = 0.0, BOOL bBreak = FALSE, BOOL bCross = TRUE);
//BOOL FaultCut1(CPointArr* ptsIn, CPointArr* ptsOut, DWORD nCutType, double dLeft = 0.0, double dRight = 0.0, BOOL bBreak = FALSE, BOOL bCross = TRUE);
//断层封堵流体、岩性
void FaultPlug(CPointArr& BreakLithLeft,CPointArr& BreakLithRight);
CString FluidRationship(CString strLeft,CString strRight);
//岩性名称关系
CString LithoRationship(CString strLeft,CString strRight);
//新版本中根据延伸方式求延伸段控制点坐标, bLeft表示是插入已有点的左侧
void GetExtendPoints(CPointArr &ptArr,BOOL bLeftWell,BOOL bTop,BOOL bLeft, std::vector<dfPoint> &ptArrControl);
//pcg文件操作
int ReadPCG_BendPens(CFile &fr,CXmlParse& xp,const short& ver);
int ReadPCG_BendControls(CFile &fr,CXmlParse& xp,const short& ver);
int ReadPCG_FaultControls(CFile &fr,CXmlParse& xp,const short& ver);
int ReadPCG_BendControlsNew(CFile &fr,CXmlParse& xp,const short& ver);
int ReadPCG_BendBrushs(CFile &fr,CXmlParse& xp,const short& ver);
int ReadPCG_Borders(CFile &fr,CXmlParse& xp,const short& ver);
int ReadPCG_Borders_ResForm(CFile &fr, CXmlParse& xp, const short& ver);
int GetLayerID(CInTrackDepthSegment *pLayer);
void GetCutFluidForPinchOut(std::vector<dfPoint>& BreakLithLeft, std::vector<dfPoint>& BreakLithRight); //计算尖灭层位被断层封堵的多边形。
void ClearLayerLines(std::vector<LAYERLINEFRAGMENT*>&pLines);
void ClearStratumFragments();
void MakeStratumFragments(); //使用层位线片段生成被断层分隔的层位区域
BOOL IsLineOnFaultLeft(LAYERLINEFRAGMENT*pLayLine, LAYERLINEFRAGMENT*pPreLine, CFaultObj* pFault);
//根据连层个数,确定连层的高度等参数
void GetBendLeftRightAndHeight(BOOL bTop,double& fLayerLeftH,double& fLayerRightH, double& valueLeft,double& valueRight,BOOL& bLeftFlag,BOOL & bRightFlag);
void ReCalculateCtrlPts(dfPoint* pResCtrls, std::vector<dfPoint>& dfPts ,BOOL bCtrlLine=TRUE);
public:
virtual int ReadPCG_Bend(CKXmlParse &xp, const short& ver);//目前看不使用20251125
virtual int ReadPCG(CKXmlParse &xp, const short& ver);
int ReadPCG_BendProperties(CKXmlParse &xp, const short& ver);
protected:
int ReadPCG_BendPens(CKXmlParse &xp, const short& ver);
int ReadPCG_BendControls(CKXmlParse &xp, const short& ver);
int ReadPCG_FaultControls(CKXmlParse &xp, const short& ver);
int ReadPCG_BendControlsNew(CKXmlParse &xp, const short& ver);
int ReadPCG_BendBrushs(CKXmlParse &xp, const short& ver);
int ReadPCG_Borders(CKXmlParse &xp, const short& ver);
int ReadPCG_Borders_ResForm(CKXmlParse &xp, const short& ver);
public:
virtual void Transform(CXyDC* pDC, float* matrix, BOOL bUndo);
virtual void TransformComputeZB(CXyDC* pDC, float* matrix, BOOL bUndo);
virtual void ComputeBend();
void GetResformCtrlPoints(int id, dfPoint* resCtrls);
CPoint2D GetPinchOutPointToWellPoint(CPoint2D PinchPoint); // 尖灭指向井的点
BOOL AddBendLayerPoint(BOOL bTop, int posPointId); //
BOOL DeleteBendLayerPoint(BOOL bTop, int posPointId);
void ReComputeBendForBreakLitho();
void InitBendControlPoints(); //按照简单的ResFormPCG规则生成bend的初始控制点
void InitBendPchoutControlPoints(CPoint2D pchPt); //按照尖灭点位置生成bend的初始控制点
void SetBendStyle(CString styleName);
int m_HitTestSelectId;// hittest时选中的bend位置=0没有=1 bend=2 bendtopline=3 bendbottomline
protected:
void CreateBendLine_ResForm(BOOL bTop, std::vector<dfPoint>& ptArrControl, std::vector<dfPoint>& BreakLithoPoints);
void CreateBendLine_OldDf(BOOL bTop, std::vector<dfPoint>& ptArrControl, std::vector<dfPoint>& BreakLithoPoints);
virtual void MoveHandleToTop_ResForm(int nHandle, CPoint2D point);
virtual void MoveHandleToBot_ResForm(int nHandle, CPoint2D point);
/*
resform pcg上下层位边数据有三种数据类型pointOldReArr是从pcg文件中直接读取的pointOldArr是按照层位边数据计算得到pointArr是将计算后的数据按照层位趋势调整过后的。
鼠标拖动的是pointArr数据拖动后需要反向计算出pcg中的数据格式。
*/
void MoveHandleToTopBottom_ResForm(int nHandle, CPoint2D point, CPointArr& pointArr, CPointArr& pointOldArr, std::vector<dfPoint>& pointOldReArr, BOOL bTop);
void ComputedTopBotLayerFromStyleLine(CCurveEx* pCurve, std::vector<dfPoint>& layerLine,dfPoint lpt, dfPoint rpt);
protected:
std::vector<CFaultObj*> m_topCutFaults,m_botCutFaults;//计算过程用到的临时变量。
};
#endif