|
|
#include "pch.h"
|
|
|
#include "IDWCalculation.h"
|
|
|
#include <array>
|
|
|
#include <ppl.h>
|
|
|
//#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<DPoint3>* 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<double>& vecX, vector<double>& vecY, vector<double>& vecZ)
|
|
|
{
|
|
|
m_pPts = new vector<DPoint3>();
|
|
|
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<array<double, 3>>& data)
|
|
|
{
|
|
|
if (m_pPts != nullptr) {
|
|
|
delete m_pPts;
|
|
|
}
|
|
|
m_pPts = new vector<DPoint3>();
|
|
|
size_t len = data.size();
|
|
|
for (int i=0;i<len;i++)
|
|
|
{
|
|
|
DPoint3 pt;
|
|
|
pt.x = data[i][0];
|
|
|
pt.y = data[i][1];
|
|
|
pt.z = data[i][2];
|
|
|
m_pPts->push_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<DPoint3>& 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);
|
|
|
|
|
|
// // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϲ<EFBFBD><CFB2>Ľ<EFBFBD><C4BD><EFBFBD>
|
|
|
// 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)
|
|
|
{ // <20><>Χ<EFBFBD><CEA7>С<EFBFBD><D0A1><EFBFBD>Ŵ<F0BDA5B7>
|
|
|
if (m_SearchResult < 0) {
|
|
|
m_R = radius;
|
|
|
radius = m_R * 2;
|
|
|
m_SearchResult = 1;
|
|
|
}
|
|
|
else if (m_SearchResult == 0)
|
|
|
{ // <20>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>С<EFBFBD><D0A1><EFBFBD><EFBFBD><EFBFBD>ֹյ<D6B9>
|
|
|
m_RInflexion = m_R; // <20>յ<EFBFBD><D5B5><EFBFBD>¼Ϊ<C2BC>ϴεĴ<CEB5><C4B4><EFBFBD>Χ
|
|
|
m_R = radius;
|
|
|
// <20><>Χ<EFBFBD>Ŵ<EFBFBD>Ϊ<EFBFBD>յ<EFBFBD><D5B5>ͺͱ<CDBA><CDB1>η<EFBFBD>Χ֮<CEA7><D6AE>
|
|
|
radius = (radius + m_RInflexion)*0.5;
|
|
|
if (abs(radius - m_R) < m_SearchTolerant) {
|
|
|
return nFoundCount;
|
|
|
}
|
|
|
m_SearchResult = 1;
|
|
|
}
|
|
|
else if(m_SearchResult==1){ // <20>ϴι<CFB4>С<EFBFBD><D0A1><EFBFBD><EFBFBD><EFBFBD>Թ<EFBFBD>С
|
|
|
m_R = radius;
|
|
|
if (m_RInflexion <= 0) {// <20><>ʼ<EFBFBD>Ŵ<F0BDA5B7>
|
|
|
radius = radius * 2;
|
|
|
}
|
|
|
else{
|
|
|
// <20>յ㲻<D5B5>䣬<EFBFBD><E4A3AC>Χ<EFBFBD>Ŵ<EFBFBD>Ϊ<EFBFBD>յ<EFBFBD><D5B5>ͺͱ<CDBA><CDB1>η<EFBFBD>Χ֮<CEA7><D6AE>
|
|
|
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)
|
|
|
{
|
|
|
// <20><>Χ<EFBFBD><CEA7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С
|
|
|
if (m_SearchResult ==-1) {
|
|
|
m_R = radius;
|
|
|
radius = m_R * 0.5;
|
|
|
m_SearchResult = 0;
|
|
|
}
|
|
|
//else if (m_SearchResult == 1 && m_RInflexion <= 0)
|
|
|
//{ // <20>״γ<D7B4><CEB3>ֹյ<D6B9>
|
|
|
// m_RInflexion = m_R;
|
|
|
// // <20><>ʼ<EFBFBD><CABC>Χ<EFBFBD><CEA7>С<EFBFBD><D0A1><EFBFBD>״γ<D7B4><CEB3>ַ<EFBFBD>Χ<EFBFBD><CEA7><EFBFBD><EFBFBD>
|
|
|
// radius = (radius + m_RInflexion)*0.5;
|
|
|
// m_SearchResult = 0;
|
|
|
//}
|
|
|
else if (m_SearchResult == 0)
|
|
|
{
|
|
|
m_R = radius;
|
|
|
if (m_RInflexion <= 0) {// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С
|
|
|
radius = radius * 0.5;
|
|
|
}
|
|
|
else{
|
|
|
// <20>ϴι<CFB4><CEB9><EFBFBD><F3A3ACB1><EFBFBD><EFBFBD>Թ<EFBFBD><D4B9><EFBFBD>
|
|
|
// <20>յ㲻<D5B5>䣬<EFBFBD><E4A3AC>Χ<EFBFBD><CEA7>СΪ<D0A1>յ<EFBFBD><D5B5>ͺͱ<CDBA><CDB1>η<EFBFBD>Χ֮<CEA7><D6AE>
|
|
|
radius = (radius + m_RInflexion)*0.5;
|
|
|
}
|
|
|
|
|
|
if (abs(radius - m_R) < m_SearchTolerant) {
|
|
|
return nFoundCount;
|
|
|
}
|
|
|
}
|
|
|
else if (m_SearchResult == 1) {// <20>ϴι<CFB4>С<EFBFBD><D0A1><EFBFBD>ι<EFBFBD><CEB9><EFBFBD><F3A3ACB3>ֹյ<D6B9>
|
|
|
// <20>յ<EFBFBD><D5B5><EFBFBD>¼Ϊ<C2BC>ϴε<CFB4>С<EFBFBD><D0A1>Χ
|
|
|
m_RInflexion = m_R;
|
|
|
m_R = radius;
|
|
|
// <20><>Χ<EFBFBD><CEA7>СΪ<D0A1>յ<EFBFBD><D5B5>ͱ<EFBFBD><CDB1>η<EFBFBD>Χ֮<CEA7><D6AE>
|
|
|
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<DPoint3> 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<CIntersectionUtil*>(intersectHelp);
|
|
|
}
|
|
|
bool IDWCalculation::IsIntersects(const Paths64* subjects, Point64& pt1, Point64& pt2)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
double IDWCalculation::GetValue(double x, double y)
|
|
|
{
|
|
|
m_SearchTimes = 0;
|
|
|
vector<DPoint3> ptsInrange;
|
|
|
m_SearchResult = -1;
|
|
|
m_RInflexion = 0;
|
|
|
FindPoints(x, y, m_R, ptsInrange);
|
|
|
|
|
|
double dFactor = -m_factor / 2;
|
|
|
dFactor = 2;
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
vector<double> vecDist;
|
|
|
vector<double> vecValue;
|
|
|
//vector<double> 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);
|
|
|
|
|
|
// // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϲ<EFBFBD><CFB2>Ľ<EFBFBD><C4BD><EFBFBD>
|
|
|
// 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);
|
|
|
}
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ܺ<EFBFBD>
|
|
|
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];
|
|
|
}
|
|
|
// <20><><EFBFBD><EFBFBD>Ȩ<EFBFBD><C8A8>
|
|
|
// <20><><EFBFBD>ս<EFBFBD><D5BD><EFBFBD>
|
|
|
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;
|
|
|
}
|