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.
91 lines
2.7 KiB
C++
91 lines
2.7 KiB
C++
#include "GridSmooth.h"
|
|
#include "QuadTree.h"
|
|
|
|
void CGridSmooth::ExcuteSmooth(std::shared_ptr<CXy> pXy, CDimension2D *pGrid,double smoothFactor)
|
|
{
|
|
if (smoothFactor < 1e-10) {
|
|
return;
|
|
}
|
|
double dGridW = pGrid->xmax()- pGrid->xmin();
|
|
double dGridH = pGrid->ymax() - pGrid->ymin();
|
|
CQuadTree quadTree(pGrid->xmin() - dGridW, pGrid->ymin() - dGridH, dGridW*3.0, dGridH*3.0, 10);
|
|
CPositionList elements;
|
|
//获取图层元素,不包含子图层
|
|
pXy->GetElement("断层", elements, true);
|
|
POSITION p = nullptr;
|
|
COne *pOne = nullptr;
|
|
POSITION pos = elements.GetHeadPosition();
|
|
NBase::dfPoint fptStart, fptEnd;
|
|
while (pos)
|
|
{
|
|
p = elements.GetNext(pos);
|
|
pOne = (COne *)pXy->GetAt(p);
|
|
int type = pOne->GetType();
|
|
switch (type)
|
|
{
|
|
case DOUBLEFOX_CURVE:
|
|
CCurveEx *pCurve = (CCurveEx *)pOne->GetValue();
|
|
for (int i = 0; i < pCurve->num-1; i++)
|
|
{
|
|
pCurve->GetPoint(i, fptStart);
|
|
pCurve->GetPoint(i, fptEnd);
|
|
LineSegment tmpSeg = { {fptStart.x0, fptStart.y0}, {fptEnd.x0, fptEnd.y0} };
|
|
quadTree.insert(tmpSeg);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
int numx = pGrid->xnum();
|
|
int numy = pGrid->ynum();
|
|
|
|
double dZMin = pGrid->range[0] - 0.001;
|
|
double dZMax = pGrid->range[1] + 0.001;
|
|
|
|
for (int i = 1; i < numx - 1; i++)
|
|
{
|
|
double dPtX = pGrid->x(i);
|
|
for (int j = 1; j < numy - 1; j++) {
|
|
double dValueCur = pGrid->Value(i, j);
|
|
if (dValueCur < dZMin || dValueCur > dZMax) {
|
|
continue;
|
|
}
|
|
|
|
double dPtY = pGrid->y(j);
|
|
double dSigma = 0;
|
|
int nCount = 0;
|
|
|
|
// Coordinates and values of neighboring points
|
|
struct Neighbor {
|
|
int di, dj;
|
|
double x, y, value;
|
|
} neighbors[8] = {
|
|
{ -1, -1, pGrid->x(i - 1), pGrid->y(j - 1), pGrid->Value(i - 1, j - 1) },
|
|
{ 0, -1, pGrid->x(i), pGrid->y(j - 1), pGrid->Value(i, j - 1) },
|
|
{ 1, -1, pGrid->x(i + 1), pGrid->y(j - 1), pGrid->Value(i + 1, j - 1) },
|
|
{ -1, 0, pGrid->x(i - 1), pGrid->y(j), pGrid->Value(i - 1, j) },
|
|
{ 1, 0, pGrid->x(i + 1), pGrid->y(j), pGrid->Value(i + 1, j) },
|
|
{ -1, 1, pGrid->x(i - 1), pGrid->y(j + 1), pGrid->Value(i - 1, j + 1) },
|
|
{ 0, 1, pGrid->x(i), pGrid->y(j + 1), pGrid->Value(i, j + 1) },
|
|
{ 1, 1, pGrid->x(i + 1), pGrid->y(j + 1), pGrid->Value(i + 1, j + 1) }
|
|
};
|
|
|
|
for (const auto& neighbor : neighbors) {
|
|
double dValueTmp = neighbor.value;
|
|
if (dValueTmp >= dZMin && dValueTmp <= dZMax) {
|
|
LineSegment querySegment = { {dPtX, dPtY}, {neighbor.x, neighbor.y} };
|
|
if (!quadTree.hasIntersection(querySegment)) {
|
|
dSigma += dValueTmp;
|
|
nCount++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (nCount > 0) {
|
|
double dAverage = dSigma / nCount;
|
|
double dValueNew = (dValueCur + dAverage * smoothFactor) / (1.0 + smoothFactor);
|
|
pGrid->SetValue(i, j, dValueNew);
|
|
}
|
|
}
|
|
}
|
|
}
|