#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; }