You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

358 lines
8.0 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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