Files
coco df489d5640 a
2026-07-03 16:05:30 +08:00

385 lines
12 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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);
}
}