This commit is contained in:
coco
2026-07-03 16:05:30 +08:00
commit df489d5640
1101 changed files with 779140 additions and 0 deletions
@@ -0,0 +1,385 @@
// MediumWenAndSch.cpp: implementation of the CMediumBasicWenAndSch class.
//
//////////////////////////////////////////////////////////////////////
#include "geomative.h"
#include "MediumBasicWenAndSch.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
typedef struct ST_LAYER_ORDER_INDEX
{
int iLayer;
std::vector<int> vtIndex;
ST_LAYER_ORDER_INDEX()
{
iLayer = 0;
vtIndex.clear();
}
}STlayerOrderIndex;
extern int g_iUILanguage;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMediumBasicWenAndSch::CMediumBasicWenAndSch(int iAR): CMedium(iAR)
{
m_fEOffsetR = 0.5;
m_fLOffsetR = 0;
}
CMediumBasicWenAndSch::~CMediumBasicWenAndSch()
{
}
bool CMediumBasicWenAndSch::GenerateSptRecElecVal(int iEAmount, int* pMaxLevel, int* pPtAmount, CPtrArray* pSptRecArray)
{
if (iEAmount < 1)
{
AfxMessageBox(_T("The number of EA_MOUNT in Wenner_Schlumberger is error!"));
return false;
}
if (NULL == pSptRecArray)
{
AfxMessageBox(_T("pSptRecArray can't be NULL!"));
return false;
}
pSptRecArray->RemoveAll();
int iC1Pos,iC2Pos,iP1Pos,iP2Pos;
int iXParam = 1;
int iTsn = 0;
CSptRecord *pSptRec = NULL;
int iLayer = 0,iTailorLayer = 0;
////////////////////modifyed by lsq 20160510//////////////////////////////////////////////////////
//AM=BN,当AM间隔选择为5或者5的倍数时,此时的下一层点的MN间间距每隔五层增加2个电极点距(MN间间距按1、3、5、7…等间隔增加),
//并且AM的间隔会暂停增加一次,测量时,AM,NB间电极间距按隔离系数由小到大的顺序等间隔增加,
// 第一层时,A=#1M=#2 N=#3 B=#4 … → … A=#57M=#58N=#59B=#60
// 第二层时,A=#1M=#3 N=#4 B=#6 … → … A=#55M=#57N=#58B=#60
// 第三层时,A=#1M=#4 N=#5 B=#8 … → … A=#53M=#56N=#57B=#60
// 第四层时,A=#1M=#5 N=#6 B=#10 … → … A=#51M=#55N=#56B=#60
// 第五层时,A=#1M=#6 N=#7 B=#12 … → … A=#49M=#54N=#55B=#60
// 第六层时,A=#1 M=#6 N=#9 B=#14 … → … A=#47M=#52N=#55B=#60
// 第七层时,A=#1M=#7 N=#10B=#16 … → … A=#45M=#51N=#54B=#60
// 第八层时,A=#1M=#8 N=#11B=#18 … → … A=#43M=#50N=#53B=#60
// 第九层时,A=#1M=#9 N=#12B=#20 … → … A=#41M=#49N=#52B=#60
// 第十层时,A=#1M=#10N=#13B=#22 … → … A=#39M=#48N=#51B=#60
// 第十一层时,A=#1 M=#10N=#15B=#24 … → … A=#37M=#46N=#51B=#60
while(TRUE)
{
iLayer++;
iTailorLayer = (iLayer-1)/5;
iC1Pos = 1;
iP1Pos = iC1Pos + iLayer - iTailorLayer;
iXParam = 1 + iTailorLayer*2;
iP2Pos = iP1Pos + iXParam;
iC2Pos = iP2Pos + iLayer - iTailorLayer;;
if (iC2Pos > iEAmount)
{
break;
}
//确定好每一层的电极初始位置之后,开始横向往右测量,此时每测一次,电极向右平移1
while(iC2Pos <= iEAmount)
{
pSptRec = new CSptRecord();
pSptRec->m_iC1 = iC1Pos;
pSptRec->m_iC2 = iC2Pos;
pSptRec->m_iP1 = iP1Pos;
pSptRec->m_iP2 = iP2Pos;
pSptRec->m_fK = CalculateCESptKVal(iC1Pos, iC2Pos, iP1Pos, iP2Pos);
//在这里这么计算是因为在修改规则之后,无法通过层数判断MN之间的间距,用这种计算方法,
//由于iXParam为奇数,所以m_iPtNum的位置距离MN真实中点的位置只差0.5个电极间距
pSptRec->m_iPtNum = iP1Pos + iXParam/2;
pSptRec->m_iLevel = GenSptRecLevel(iC1Pos, iC2Pos, iP1Pos, iP2Pos);
pSptRec->m_colorREF = RGB(0, 255, 0);
pSptRec->m_iN = 1;
pSptRec->m_bIsSel = TRUE;
pSptRec->m_iTsn = ++iTsn;
pSptRecArray->Add(pSptRec);
iC1Pos++;
iC2Pos++;
iP1Pos++;
iP2Pos++;
}
}
*pPtAmount = pSptRecArray->GetSize();
*pMaxLevel = iLayer-1;
return true;
}
float CMediumBasicWenAndSch::CalculateCESptKVal(float fA, float fB, float fX, float fY)
{
//这里K值的计算公式为: k = n(n+x)*pai*a/x
//其中a为最小电极间距,我们默认为1,由GD10主机设置
//n:指的是AM之间的间隔系数(即AM=n*a)
//x:指的是MN之间的间隔系数(即MN=x*a)
if (fX == fY)
{
if (LANG_ZHCN == g_iUILanguage)
AfxMessageBox(_T("MN的距离不能为零!"));
else
AfxMessageBox(_T("The distance between M and N can not be zero,please check!"));
return 0;
}
float fNparam = fX - fA;
float fXParam = fY - fX;
return (VAL_PI*fNparam*(fNparam+fXParam)) / fXParam;
}
void CMediumBasicWenAndSch::CalculateSptPtLoc(int iMul,CSptRecord* pSptRecord)
{
int iOffsetL = (int)VAL_ZERO;
int iOffsetR = (int)VAL_ZERO;
int iLevel = pSptRecord->m_iLevel;
int iPtNum = pSptRecord->m_iPtNum;
//此时的OFFSETL相当于每一层第一次ABMN中的点的矩形初始位置,其中X轴的坐标间距为8
//46为坐标轴起始点在X方向的距离
//其中46+ (6+2)*iMul+ 4*iMul*(iLevel-1)*2就是M的起始位置
//iOffsetL = (6+2)*iMul+50+4*iMul*(iLevel-1)*2+(iMul-2);
// iOffsetL = 46+ (6+2)*iMul+ 4*iMul*(iLevel-1)*2 + iMul* ((pSptRecord->m_iP2 - pSptRecord->m_iP1)*(6+2)/2 - 3) ;
// iOffsetR = iOffsetL+6*iMul;
iOffsetL = 46;
iOffsetR = iOffsetL+6*iMul;
//矩形的X轴的位置有OFFSETL 再加上向右的偏移距离组成,向右的偏移距离即是全部电极每测一次向右偏移的距离
//举例来说,此时OFFSETL相当于此时的中心点的起始位置,iPtNum-1则相当于此时向右偏移的次数
//其中圆点的半径为3,在这里加4是因为iPtNum距离真正中心点的位置差半个电极间距,
pSptRecord->m_recPtArea.left = iOffsetL+(6+2)*iMul*(iPtNum-1) + (4-3)*iMul;
pSptRecord->m_recPtArea.top = 50+(6+2)*iMul*(iLevel-1);
pSptRecord->m_recPtArea.right = iOffsetR+(6+2)*iMul*(iPtNum-1)+ (4-3)*iMul;
pSptRecord->m_recPtArea.bottom = (50+6*iMul)+(6+2)*iMul*(iLevel-1);
pSptRecord->m_fPtCenterX = (float)(pSptRecord->m_recPtArea.left + pSptRecord->m_recPtArea.right)/2;
pSptRecord->m_fPtCenterY = (float)(pSptRecord->m_recPtArea.top + pSptRecord->m_recPtArea.bottom )/2;
pSptRecord->m_fPtRadius = (float)(abs((int)(pSptRecord->m_fPtCenterX) - pSptRecord->m_recPtArea.left));
}
int CMediumBasicWenAndSch::GetMaxLevelByEAmount(int iEAmount)
{
if (iEAmount < 4)
{
return 0;
}
int iC1Pos,iC2Pos,iP1Pos,iP2Pos;
int iXParam = 1;
int iLayer = 0,iTailorLayer = 0;
while(TRUE)
{
iLayer++;
iTailorLayer = (iLayer-1)/5;
iC1Pos = 1;
iP1Pos = iC1Pos + iLayer - iTailorLayer;
iXParam = 1 + iTailorLayer*2;
iP2Pos = iP1Pos + iXParam;
iC2Pos = iP2Pos + iLayer -iTailorLayer;
if (iC2Pos > iEAmount)
{
break;
}
}
return iLayer-1;
}
void CMediumBasicWenAndSch::CalculateTdPtLoc(const CRect& vRect, const int& iEAmount, int& iMaxLevel, CRect& lRect, int& iSmWidth, int& iSmHeight, CPtrArray* pTdRecArray)
{
int iTop = 0;
int iBottom = 0;
int iLeft = 0;
int iRight = 0;
int iRectWidth = 0;
int iRectHeight = 0;
iSmWidth = 0;
iSmHeight = 0;
int iLevel = 0;
int iPos = 0;
int iIndex = 0;
int iEOffset = 0;
int iLOffset = 0;
int iNewEAmount = iEAmount;
if (iEAmount%ELECTRODE_AMOUNT_PERCABLE != 0)
{
iNewEAmount =ELECTRODE_AMOUNT_PERCABLE * (1 + iEAmount/ELECTRODE_AMOUNT_PERCABLE);
}
iMaxLevel = this->GetMaxLevelByEAmount(iNewEAmount);
int iXEAmount = (m_iEndPole > m_iStartPole) ? m_iEndPole - m_iStartPole +1 : iEAmount;
lRect = vRect;
//已此时的CRect的中心移动边来缩小输入的rect的大小
lRect.DeflateRect(141, 40, 61, 40);
//返回大于或者等于指定表达式的最小整数,value 如果有小数部分则进一位
//iEAmount为电极的个数,非测点总数,第一层的测点数是最接近电极数的,在倒三角的剖面中
iSmWidth = (int)ceil(lRect.Width()*1.0/iXEAmount);
iSmHeight = (int)ceil(lRect.Height()*1.0/iMaxLevel);
//将iSmWidth变成奇数,那么iSmWidth-1此时将成为偶数,再用它去乘以任何数也都将是偶数
if (fmod((double)iSmWidth, 2.0) == 0.0)
{
iSmWidth++;
}
//由于极端的AM装置中,那么在第一层的最后一个位置,此时AM的点的坐标将会超过X轴的坐标系,
//所以此时要留有一个装置的余量
iRectWidth = iSmWidth+(iSmWidth-1)*(iXEAmount-1);
//iRectWidth = iSmWidth+(iSmWidth-1)*(iEAmount-2);
if (fmod((double)iSmHeight, 2.0) == 0.0)
{
iSmHeight++;
}
iRectHeight = iSmHeight+(iSmHeight-1)*(iMaxLevel-1);
if (fmod(lRect.Width()-iRectWidth, 2.0) == 0.0)
{
iLeft = (lRect.Width()-iRectWidth)/2;
iRight = (lRect.Width()-iRectWidth)/2;
}
else
{
iLeft = (lRect.Width()-iRectWidth)/2+1;
iRight = (lRect.Width()-iRectWidth)/2;
}
if (fmod(lRect.Height()-iRectHeight, 2.0) == 0.0)
{
iTop = (lRect.Height()-iRectHeight)/2;
iBottom = (lRect.Height()-iRectHeight)/2;
}
else
{
iTop = (lRect.Height()-iRectHeight)/2+1;
iBottom = (lRect.Height()-iRectHeight)/2;
}
lRect.DeflateRect(iLeft, iTop, iRight, iBottom);
CRsp2DTdRecord* pRsp2DTdRecord = NULL;
//iLOffset和iEOffset用来计算中间点和测点之间的偏差
//比如AMN模式中,点在MN的中点位置,此时m_iPosInLevel取得是M点的位置,
//那么iLOffset和iEOffset则用来计算M和中点位置之间的偏差
iEOffset = (int)((iSmWidth-1)*m_fEOffsetR);
iLOffset = (int)((iSmWidth-1)*m_fLOffsetR);
while (iIndex < pTdRecArray->GetSize())
{
pRsp2DTdRecord = (CRsp2DTdRecord*)(pTdRecArray->GetAt(iIndex));
iLevel = pRsp2DTdRecord->m_iLevel-1;
iPos = pRsp2DTdRecord->m_iPosInLevel-1 - m_iStartPole + 1;
pRsp2DTdRecord->m_recPtArea.SetRectEmpty();
pRsp2DTdRecord->m_recPtArea.SetRect(lRect.left+iEOffset+iLOffset*(int)(iLevel/3)+(iSmWidth-1)*iPos, lRect.top+(iSmHeight-1)*iLevel,
lRect.left+iEOffset+iLOffset*(int)(iLevel/3)+(iSmWidth-1)*iPos+iSmWidth, lRect.top+(iSmHeight-1)*iLevel+iSmHeight);
iIndex++;
}
}
void CMediumBasicWenAndSch::ReSortPoint(CPtrArray *f_ptr)
{
//在同一层内,取中点作为间隔点,左右两边分别跑跑,跑完后在取中间点
//例如总共有5个点时,序号分别为1-5,此时的跑极顺序为1,4,2,5,3
//在不同层时,按照层数的从小到大进行跑极
CSptRecord *pSptRecord = NULL;
CSptRecord *pTmp = NULL;
int iMaxLevel = ((CSptRecord *)(f_ptr->GetAt(f_ptr->GetSize()-1)))->m_iLevel;
if (0 == iMaxLevel)
{
return;
}
int nPreCnt = 0;
std::vector<STlayerOrderIndex> vtLayerOrderInfo;
vtLayerOrderInfo.clear();
int i = 1;
for (; i <= iMaxLevel; i++)
{
int nCurLayerCnt = 0;
for (int j = nPreCnt; j < f_ptr->GetSize(); j++)
{
pTmp = (CSptRecord*)(f_ptr->GetAt(j));
if (i == pTmp->m_iLevel)
{
nCurLayerCnt++;
}
else
break;
}
STlayerOrderIndex stLayerOrder;
stLayerOrder.iLayer = 1;
stLayerOrder.vtIndex.clear();
bool bIsOdd = (nCurLayerCnt %2 == 0) ? false : true;
int iMidIndex = 0;
if (bIsOdd)
{
iMidIndex = (nCurLayerCnt+1)/2;
stLayerOrder.vtIndex.push_back(nPreCnt+iMidIndex-1);
for (int iIndex = 1; iIndex <iMidIndex; iIndex++)
{
stLayerOrder.vtIndex.push_back(nPreCnt+iMidIndex-iIndex-1);
stLayerOrder.vtIndex.push_back(nPreCnt+iMidIndex+iIndex-1);
}
}
else
{
iMidIndex = nCurLayerCnt/2;
for (int iIndex = 1; iIndex <=iMidIndex; iIndex++)
{
stLayerOrder.vtIndex.push_back(nPreCnt+iMidIndex-(iIndex-1)-1);
stLayerOrder.vtIndex.push_back(nPreCnt+iMidIndex+iIndex-1);
}
}
vtLayerOrderInfo.push_back(stLayerOrder);
nPreCnt += nCurLayerCnt;
}
CPtrArray newPtArr;
newPtArr.RemoveAll();
int iMaxIndex = vtLayerOrderInfo[0].vtIndex.size();
for (int iIndex = 0; iIndex < iMaxIndex; iIndex++)
{
for (i = 1; i <= iMaxLevel; i++)
{
if (iIndex > vtLayerOrderInfo[i-1].vtIndex.size()-1)
{
continue;
}
int iOrderIndex = vtLayerOrderInfo[i-1].vtIndex[iIndex];
pSptRecord = (CSptRecord*)f_ptr->GetAt(iOrderIndex);
newPtArr.Add(pSptRecord);
}
}
if (newPtArr.GetSize() != f_ptr->GetSize())
{
if (LANG_ZHCN == g_iUILanguage)
AfxMessageBox(_T("数据重排错误!"));
else
AfxMessageBox(_T("resort data error!"));
return;
}
f_ptr->RemoveAll();
int iTsn = 0;
for (int k = 0; k < newPtArr.GetSize(); k++)
{
pSptRecord = (CSptRecord*)newPtArr.GetAt(k);
pSptRecord->m_iTsn = ++iTsn;
f_ptr->Add(pSptRecord);
}
}