// 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 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=#1,M=#2, N=#3, B=#4 … → … A=#57,M=#58,N=#59,B=#60 // 第二层时,A=#1,M=#3, N=#4, B=#6 … → … A=#55,M=#57,N=#58,B=#60 // 第三层时,A=#1,M=#4, N=#5, B=#8 … → … A=#53,M=#56,N=#57,B=#60 // 第四层时,A=#1,M=#5, N=#6, B=#10 … → … A=#51,M=#55,N=#56,B=#60 // 第五层时,A=#1,M=#6, N=#7, B=#12 … → … A=#49,M=#54,N=#55,B=#60 // 第六层时,A=#1, M=#6, N=#9, B=#14 … → … A=#47,M=#52,N=#55,B=#60 // 第七层时,A=#1,M=#7, N=#10,B=#16 … → … A=#45,M=#51,N=#54,B=#60 // 第八层时,A=#1,M=#8, N=#11,B=#18 … → … A=#43,M=#50,N=#53,B=#60 // 第九层时,A=#1,M=#9, N=#12,B=#20 … → … A=#41,M=#49,N=#52,B=#60 // 第十层时,A=#1,M=#10,N=#13,B=#22 … → … A=#39,M=#48,N=#51,B=#60 // 第十一层时,A=#1, M=#10,N=#15,B=#24 … → … A=#37,M=#46,N=#51,B=#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 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 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); } }