Files
envi-code/SourceCode/Code2026/ThunderProof/FoldToolKit.cpp
T
2026-09-28 15:28:50 +08:00

472 lines
8.6 KiB
C++

#include "stdafx.h"
#include "FoldToolKit.h"
CFoldToolKit* CFoldToolKit::m_pInstance = NULL;
CFoldToolKit* CFoldToolKit::Instance()
{
if (m_pInstance == NULL)
{
m_pInstance = new CFoldToolKit;
}
return m_pInstance;
}
void CFoldToolKit::DisInstance()
{
if (m_pInstance)
{
delete m_pInstance;
}
}
CFoldToolKit::CFoldToolKit(void)
{
IniEquation();
}
CFoldToolKit::~CFoldToolKit(void)
{
if (m_pInstance)
{
delete m_pInstance;
}
}
void CFoldToolKit::IniEquation()
{
//初始化公式map
Equation equa;
//公式 0
//equa.InputK(1.62461,-0.09877,-0.00355,-0.00219);
equa.InputK(1.61761,-0.09964,-0.004,-0.00207);
m_Equations.insert(std::make_pair(CString(_T("0.0")),equa));
//公式 0.1
//equa.InputK(1.47755,-0.13857,0.01224,-0.0032);
equa.InputK(1.47641,-0.13735,0.01189,-0.00317);
m_Equations.insert(std::make_pair(CString(_T("0.1")),equa));
//公式 0.2
//equa.InputK(1.35556,-0.1276,0.0123,-0.0031);
equa.InputK(1.34738,-0.11862,0.00969,-0.00288);
m_Equations.insert(std::make_pair(CString(_T("0.2")),equa));
//公式 0.3
//equa.InputK(1.25006,-0.13541,0.01628,-0.00316);
equa.InputK(1.24022,-0.12442,0.01305,-0.00289);
m_Equations.insert(std::make_pair(CString(_T("0.3")),equa));
//公式 0.4
//equa.InputK(1.16093,-0.09792,0.0053,-0.00207);
equa.InputK(1.16073,-0.09698,0.00508,-0.00206);
m_Equations.insert(std::make_pair(CString(_T("0.4")),equa));
//公式 0.5
// equa.InputK(1.07223,-0.08827,0.00562,0.0021);
equa.InputK(1.07195,-0.08759,0.00542,-0.00209);
m_Equations.insert(std::make_pair(CString(_T("0.5")),equa));
//公式 0.7
// equa.InputK(1.02243,-0.08841,0.0024,-0.00148);
equa.InputK(1.01274,-0.07973,0.00034,-0.00134);
m_Equations.insert(std::make_pair(CString(_T("0.7")),equa));
//公式 0.9
// equa.InputK(0.9485,-0.06138,-0.00584,0);
equa.InputK(0.9509,-0.06759,-0.00438,-0.00074);
m_Equations.insert(std::make_pair(CString(_T("0.9")),equa));
}
BOOL CFoldToolKit::CalcFoldBx(double dH1,double dH2,double dDist,double dHx,FoldCalcResult& FoldRes)
{
memset(&FoldRes,0,sizeof(FoldCalcResult));
double dBx = 0.0;
double dMinH = min(dH1,dH2);
double dMaxH = max(dH1,dH2);
double dHa = dMinH - dHx;
if (dMinH < 1e-6)
{
return FALSE;
}
if (dHa < 1e-6)
{
//最小高度 小于等于 保护高度
dBx = 0;
return FALSE;
}
double dP = 0.0;
//计算P
if (dMinH - 30 < 1e-6)
{
//高度 小于等于30m
dP = 1.0;
}
else
{
//高度大于30m
dP = 5.5 / pow(dMinH,0.5);
if (dMinH - 120 > 1e-6)
{
//高度大于 120
dP = 5.5 / pow(120,0.5);
}
}
//计算 有效距离
double dD = CalcEffectDist(dH1,dH2,dDist,dHx);
//计算X
double dX = 0.0;
dX = dD / (dHa * dP);
if (dX - 7.0 > -1e-6)
{
//dX 大于等于 7
dBx = 0.0;
return FALSE;
}
//计算BX
Equation eq1,eq2;
//确定公式
double dEquK = dHx/dMinH,dEquK1 = 0.0,dEquK2 = 0.0;
double dY1 = 0.0,dY2 = 0.0,dY = 0.0;
CString sEquK1,sEquK2,sOut;
//0 ~ 0.7
int i = 0;
i = (int)(dEquK * 10 + 0.5);
double dTemp = double(i)/10;
sEquK1.Format(_T("%.1f"),dTemp);
dEquK1 = _tstof(sEquK1);
sEquK2.Format(_T("%.1f"),dEquK1 + 0.1);
if (dEquK - 0.5 > -1e-6 && 0.7 - dEquK > -1e-6)
{
// 0.5 ~ 0.7 缺少0.6和0.8的公式
sEquK1 = _T("0.5");
sEquK2 = _T("0.7");
}
if (dEquK - 0.7 > 1e-6)
{
// 0.7 ~ 1 缺少0.6和0.8的公式
sEquK1 = _T("0.7");
sEquK2 = _T("0.9");
}
if (m_Equations.find(sEquK1) == m_Equations.end())
{
return FALSE;
}
if (m_Equations.find(sEquK2) == m_Equations.end())
{
return FALSE;
}
//差值计算
dEquK1 = _tstof(sEquK1);
dEquK2 = _tstof(sEquK2);
eq1 = m_Equations[sEquK1];
eq2 = m_Equations[sEquK2];
dY1 = CalcFoldY(eq1,dX);
dY2 = CalcFoldY(eq2,dX);
dY = dY1 - ((fabs(dEquK - dEquK1)/fabs(dEquK1 - dEquK2))*fabs(dY1 - dY2));
dBx = dY*(dMinH - dHx) * dP;
// 2012/3/23 支持山地坡地计算
int nCheck = -1;
CRegProperty reg(GetRegLocation(), _T("Thunder"));
reg.SetTopRootKey(HKEY_CURRENT_USER);
if (!reg.GetValue(KEY_FOLD_HILL_HILLSIDE, nCheck))
{
nCheck = 0;
}
//计算h0
double dH0 = dMinH - dD/(7 * dP);
if (nCheck)
{
// 2012/3/23
dBx *= 0.75;
dH0 = dMinH - dD / (5 * dP);
}
//返回计算结果
FoldRes.m_dBx = dBx;
FoldRes.m_dEffectD = dD;
FoldRes.m_dY = dY;
FoldRes.m_dH0 = dH0;
if (fabs(dH0 - dHx) < 1e-6 && dBx > 1e-6)
{
//保护高度等于 h0
dBx = 0.0;
return TRUE;
}
if (dH0 - dHx < 1e-6)
{
//保护高度 大于 h0
return FALSE;
}
if (dBx < -1e-6)
{
//dBx < 0. 等于0时为临界,返回true
return FALSE;
}
return TRUE;
}
BOOL CFoldToolKit::CalcFoldBx(double dH1,double dH2,double dDist,double dHx,double& dBx)
{
double dMinH = min(dH1,dH2);
double dMaxH = max(dH1,dH2);
double dHa = dMinH - dHx;
if (dMinH < 1e-6)
{
return FALSE;
}
if (dHa < 1e-6)
{
//最小高度 小于等于 保护高度
dBx = 0;
return FALSE;
}
double dP = 0.0;
//计算P
if (dMinH - 30 < 1e-6)
{
//高度 小于等于30m
dP = 1.0;
}
else
{
//高度大于30m
dP = 5.5 / pow(dMinH,0.5);
if (dMinH - 120 > 1e-6)
{
//高度大于 120
dP = 5.5 / pow(120,0.5);
}
}
//计算 有效距离
double dD = CalcEffectDist(dH1,dH2,dDist,dHx);
//计算X
double dX = 0.0;
dX = dD / (dHa * dP);
if (dX - 7.0 > -1e-6)
{
//dX 大于等于 7
dBx = 0.0;
return FALSE;
}
//计算BX
Equation eq1,eq2;
//确定公式
double dEquK = dHx/dMinH,dEquK1 = 0.0,dEquK2 = 0.0;
double dY1 = 0.0,dY2 = 0.0,dY = 0.0;
CString sEquK1,sEquK2,sOut;
//0 ~ 0.7
int i = 0;
i = (int)(dEquK * 10+0.5);
double dTemp = double(i)/10;
sEquK1.Format(_T("%.1f"),dTemp);
dEquK1 = _tstof(sEquK1);
sEquK2.Format(_T("%.1f"),dEquK1 + 0.1);
if (dEquK - 0.5 > -1e-6 && 0.7 - dEquK > -1e-6)
{
// 0.5 ~ 0.7 缺少0.6和0.8的公式
sEquK1 = _T("0.5");
sEquK2 = _T("0.7");
}
if (dEquK - 0.7 > 1e-6)
{
// 0.7 ~ 1 缺少0.6和0.8的公式
sEquK1 = _T("0.7");
sEquK2 = _T("0.9");
}
if (m_Equations.find(sEquK1) == m_Equations.end())
{
return FALSE;
}
if (m_Equations.find(sEquK2) == m_Equations.end())
{
return FALSE;
}
//差值计算
dEquK1 = _tstof(sEquK1);
dEquK2 = _tstof(sEquK2);
eq1 = m_Equations[sEquK1];
eq2 = m_Equations[sEquK2];
dY1 = CalcFoldY(eq1,dX);
dY2 = CalcFoldY(eq2,dX);
dY = dY1 - ((fabs(dEquK - dEquK1)/fabs(dEquK1 - dEquK2))*fabs(dY1 - dY2));
dBx = dY*(dMinH - dHx) * dP;
// 计算h0 支持山地坡地计算 2012/3/21
int nCheck = -1;
CRegProperty reg(GetRegLocation(), _T("Thunder"));
reg.SetTopRootKey(HKEY_CURRENT_USER);
if (!reg.GetValue(KEY_FOLD_HILL_HILLSIDE, nCheck))
{
nCheck = 0;
}
//计算h0
double dH0 = dMinH - dD/(7 * dP);
if (nCheck)
{
// 2012/3/23
dBx *= 0.75;
dH0 = dMinH - dD / (5 * dP);
}
if (fabs(dH0 - dHx) < 1e-6 && dBx > 1e-6)
{
//保护高度等于 h0
dBx = 0.0;
return TRUE;
}
if (dH0 - dHx < 1e-6)
{
//保护高度 大于 h0
return FALSE;
}
if (dBx < -1e-6)
{
//dBx < 0. 等于0时为临界,返回true
return FALSE;
}
return TRUE;
}
double CFoldToolKit::CalcEffectDist(double dH1,double dH2,double dDist,double dHx)
{
double dEffectD = dDist;
if (fabs(dH1 - dH2) < 1e-6)
{
return dEffectD;
}
double dMinH = min(dH1,dH2);
double dMaxH = max(dH1,dH2);
//计算P max
double dPMax = 0.0;
if (dMaxH - 30 < 1e-6)
{
//高度 小于等于30m
dPMax = 1.0;
}
else
{
//高度大于30m
dPMax = 5.5 / pow(dMaxH,0.5);
if (dMaxH - 120 > 1e-6)
{
//高度大于 120
dPMax = 5.5 / pow(120,0.5);
}
}
// 2012/3/21 for 支持山地坡地计算
int nCheck = -1;
CRegProperty reg(GetRegLocation(), _T("Thunder"));
reg.SetTopRootKey(HKEY_CURRENT_USER);
if (!reg.GetValue(KEY_FOLD_HILL_HILLSIDE, nCheck))
{
nCheck = 0;
}
//计算D
if (nCheck)
{
if(0.5*dMaxH - dMinH < 1e-6)
{
dEffectD = dDist - (dMaxH - dMinH)*dPMax*0.75;
}
else
{
dEffectD = dDist - (1.5*dMaxH - 2*dMinH)*dPMax*0.75;
}
}
else
{
if(0.5*dMaxH - dMinH < 1e-6)
{
dEffectD = dDist - (dMaxH - dMinH)*dPMax;
}
else
{
dEffectD = dDist - (1.5*dMaxH - 2*dMinH)*dPMax;
}
}
return dEffectD;
}
double CFoldToolKit::CalcFoldY(const Equation& equ,double dX)
{
//y = k0 + k1*x + k2*x*x + k3*x*x*x
double dY = 0.0;
dY = equ.m_dK0 + equ.m_dK1*dX + equ.m_dK2*dX*dX + equ.m_dK3*dX*dX*dX;
return dY;
}
double CFoldToolKit::CalcFoldRx(double dH,double dHx)
{
//计算保护半径
double dRx = 0.0;
double dHTemp = dH;
double dP = 0.0;
if (dHTemp - dHx < 1e-3)
{
return dRx;
}
//计算P
if (dHTemp - 30 < 1e-6)
{
//高度 小于等于30m
dP = 1.0;
}
else
{
//高度大于30m
if (dHTemp - 120 > 1e-6)
{
//高度大于 120
dHTemp = 120;
}
dP = 5.5 / pow(dHTemp,0.5);
}
if(0.5*dHTemp - dHx < 1e-6)
dRx = (dH - dHx)*dP;
else
dRx = (1.5*dH- 2*dHx)*dP;
// 2012/3/23 山地坡地计算时,针高不变,保护范围减小,原范围乘以0.75
int nCheck = -1;
CRegProperty reg(GetRegLocation(), _T("Thunder"));
reg.SetTopRootKey(HKEY_CURRENT_USER);
if (!reg.GetValue(KEY_FOLD_HILL_HILLSIDE, nCheck))
{
nCheck = 0;
}
if (nCheck)
{
dRx *= 0.75;
}
return dRx;
}