#include "pch.h" #include "IDWCalculation.h" #include #include //#include "clipper2\clipper.export.h" using namespace concurrency; //using namespace Clipper2Lib; IDWCalculation::IDWCalculation() :m_pX(nullptr), m_pY(nullptr), m_pZ(nullptr), m_pPts(nullptr), //m_pFaultages(nullptr), m_K(9), m_Area(50), m_R(100), m_SearchTimes(0), m_SearchResult(-1), m_SearchTolerant(1.5), m_IntersectHelp(nullptr) { } IDWCalculation::~IDWCalculation() { if (m_bCreated) { delete m_pX; m_pX = nullptr; delete m_pY; m_pY = nullptr; delete m_pZ; m_pZ = nullptr; delete m_pPts; m_pPts = nullptr; } } void IDWCalculation::SetSortedData(vector* pData) { m_pPts = pData; m_bCreated = FALSE; } bool IDWCalculation::PointSort(DPoint3& pt1, DPoint3& pt2) { return pt1.x < pt2.x || (pt1.x == pt2.x && pt1.y < pt2.y); } void IDWCalculation::SetData(vector& vecX, vector& vecY, vector& vecZ) { m_pPts = new vector(); this->m_pX = &vecX; this->m_pY = &vecY; this->m_pZ = &vecZ; int nLen = vecX.size(); for (int i = 0; i < nLen; i++) { DPoint3 pt; pt.x = vecX[i]; pt.y = vecY[i]; pt.z = vecZ[i]; m_pPts->push_back(pt); } parallel_sort(m_pPts->begin(), m_pPts->end(), IDWCalculation::PointSort); m_R = sqrt(m_K*(m_Area / (nLen * M_PI))) *0.5; m_bCreated = TRUE; } void IDWCalculation::SetData(vector>& data) { if (m_pPts != nullptr) { delete m_pPts; } m_pPts = new vector(); size_t len = data.size(); for (int i=0;ipush_back(pt); } parallel_sort(m_pPts->begin(), m_pPts->end(), IDWCalculation::PointSort); //for (int i = 0; i < len; i++) //{ // TRACE("%lf,%lf,%lf\r\n", m_pPts->at(i).x, m_pPts->at(i).y, m_pPts->at(i).z); //} m_R = sqrt(m_K*(m_Area / (len * M_PI))) *0.5; m_bCreated = TRUE; } int IDWCalculation::FindPoints(double centerX, double centerY, double radius, vector& ptsInrange) { m_SearchTimes++; double dLeft = centerX - radius; double dRight = centerX + radius; double dBottorm = centerY - radius; double dTop = centerY + radius; double dDistance = radius * radius; int nLen = m_pPts->size(); double dPtX, dPtY; int nFaultTimes = 0; for (int i = 0; i < nLen; i++) { dPtX = m_pPts->at(i).x; dPtY = m_pPts->at(i).y; if (dPtX < dLeft || dPtY < dBottorm) { continue; } if (dPtX > dRight && dPtY > dTop) { break; } if ((dPtX - centerX)*(dPtX - centerX) + (dPtY - centerY)*(dPtY - centerY) <= dDistance) { //if (m_pFaultages && m_pFaultages->size() > 0) //{ // PathD lineClip; // lineClip.push_back(PointD(centerX, centerY)); // lineClip.push_back(PointD(dPtX, dPtY)); // PathsD clip, solutionClosed, solutionOpen; // clip.push_back(lineClip); // ClipperD clipperD; // clipperD.AddOpenSubject(clip); // clipperD.AddClip(*m_pFaultages); // clipperD.Execute(ClipType::Intersection, FillRule::NonZero, solutionClosed, solutionOpen); // // 计算与断层的交点 // if (solutionOpen.size() > 0) { // nFaultTimes++; // //if (nFaultTimes == 10) { // // return ptsInrange.size(); // //} // continue; // } //} ptsInrange.push_back(m_pPts->at(i)); if ((ptsInrange.size() /*+ (size_t)nFaultTimes*/) >= (m_K * 2)) { break; } } } int nFoundCount = ptsInrange.size() + nFaultTimes; if (m_SearchTimes >= 20) { m_R = radius; return nFoundCount; } if (abs(nFoundCount - m_K)<=3) { m_R = radius; return nFoundCount; } else if (nFoundCount < m_K) { // 范围过小,逐渐放大 if (m_SearchResult < 0) { m_R = radius; radius = m_R * 2; m_SearchResult = 1; } else if (m_SearchResult == 0) { // 由过大变为过小,出现拐点 m_RInflexion = m_R; // 拐点记录为上次的大范围 m_R = radius; // 范围放大为拐点和和本次范围之间 radius = (radius + m_RInflexion)*0.5; if (abs(radius - m_R) < m_SearchTolerant) { return nFoundCount; } m_SearchResult = 1; } else if(m_SearchResult==1){ // 上次过小本次仍过小 m_R = radius; if (m_RInflexion <= 0) {// 初始逐渐放大 radius = radius * 2; } else{ // 拐点不变,范围放大为拐点和和本次范围之间 radius = (radius + m_RInflexion)*0.5; } if (abs(radius - m_R) < m_SearchTolerant) { return nFoundCount; } } ptsInrange.clear(); FindPoints(centerX, centerY, radius, ptsInrange); } else if (nFoundCount > m_K) { // 范围过大,逐渐缩小 if (m_SearchResult ==-1) { m_R = radius; radius = m_R * 0.5; m_SearchResult = 0; } //else if (m_SearchResult == 1 && m_RInflexion <= 0) //{ // 首次出现拐点 // m_RInflexion = m_R; // // 开始范围过小,首次出现范围过大 // radius = (radius + m_RInflexion)*0.5; // m_SearchResult = 0; //} else if (m_SearchResult == 0) { m_R = radius; if (m_RInflexion <= 0) {// 初始逐渐缩小 radius = radius * 0.5; } else{ // 上次过大,本次仍过大 // 拐点不变,范围缩小为拐点和和本次范围之间 radius = (radius + m_RInflexion)*0.5; } if (abs(radius - m_R) < m_SearchTolerant) { return nFoundCount; } } else if (m_SearchResult == 1) {// 上次过小本次过大,出现拐点 // 拐点记录为上次的小范围 m_RInflexion = m_R; m_R = radius; // 范围缩小为拐点和本次范围之间 radius = (radius + m_RInflexion)*0.5; if (abs(radius - m_R) < m_SearchTolerant) { return nFoundCount; } m_SearchResult = 0; } ptsInrange.clear(); FindPoints(centerX, centerY, radius, ptsInrange); } else { m_R = radius; return nFoundCount; } return nFoundCount; } double IDWCalculation::TestR(double x, double y) { m_SearchTimes = 0; vector ptsInrange; m_SearchResult = -1; m_RInflexion = 0; FindPoints(x, y, m_R, ptsInrange); return m_R; } void IDWCalculation::SetSearchR(double r) { m_R = r; } void IDWCalculation::SetFaultageHelp(const CIntersectionUtil* intersectHelp) { this->m_IntersectHelp = const_cast(intersectHelp); } bool IDWCalculation::IsIntersects(const Paths64* subjects, Point64& pt1, Point64& pt2) { return false; } double IDWCalculation::GetValue(double x, double y) { m_SearchTimes = 0; vector ptsInrange; m_SearchResult = -1; m_RInflexion = 0; FindPoints(x, y, m_R, ptsInrange); double dFactor = -m_factor / 2; dFactor = 2; // 计算距离 vector vecDist; vector vecValue; //vector vecDist; size_t len = ptsInrange.size(); if (len == 0) { return -1E300; } double dDist = 0,dDistPow = 0; //double dSearchDist = m_searchDistance * m_searchDistance; for (size_t i = 0; i < len; i++) { DPoint3 ptCur = ptsInrange.at(i); if (m_IntersectHelp != nullptr) { if (m_IntersectHelp->Intersects(LineSegment(Point64(x, y), Point64(ptCur.x, ptCur.y)))) { continue; } } //if (m_pFaultages && m_pFaultages->size() > 0) //{ // Path64 lineClip; // lineClip.push_back(Point64(ptCur.x, ptCur.y)); // lineClip.push_back(Point64(x, y)); // Paths64 clip, solutionClosed, solutionOpen; // clip.push_back(lineClip); // Clipper64 clipperD; // clipperD.AddOpenSubject(clip); // clipperD.AddClip(*m_pFaultages); // clipperD.Execute(ClipType::Intersection, FillRule::NonZero, solutionClosed, solutionOpen); // // 计算与断层的交点 // if (solutionOpen.size() > 0) { // continue; // } //} dDist = (x - ptCur.x) * (x - ptCur.x) + (y - ptCur.y) * (y - ptCur.y); if (dDist < 1E-50) { return ptsInrange.at(i).z; } dDistPow = pow(dDist, -dFactor*0.5); vecDist.push_back(dDistPow); vecValue.push_back(ptCur.z); } // 距离总和 int nValueCount = vecDist.size(); if (nValueCount==0) { return -1E301; } double dSigmaDis = 0; for (size_t i = 0; i < nValueCount; i++) { /*dSigmaDis += pow(1.0 / vecDist[i], m_factor);*/ dSigmaDis += vecDist[i]; } // 计算权重 // 最终结果 double dValue = 0; double dWeight = 0; for (size_t i = 0; i < nValueCount; i++) { //dWeight = vecDist[i] / dSigmaDis; //dValue += vecValue.at(i)*dWeight; dValue += (vecValue.at(i) * vecDist[i]) / dSigmaDis; } return dValue; } void IDWCalculation::SetArea(double area) { this->m_Area = area; }