#include "algo/VolumeBuilder.hpp" #include #include #include #include #include #include "algo/IdwInterpolator.hpp" namespace geopro::core { namespace { // 某轴:优先用 cell 间距;若包络 ext 过大致格数超 kMaxVolumeDim,则**放大间距**使 maxDim 格跨满 ext // (分辨率降低,但**不截断**——否则跨 TM 多剖面相距 > maxDim×cell 时,远端剖面落网格外、丢失)。 void fitAxis(double ext, double cell, double& outCell, int& outN) { if (!(ext > 0.0) || !(cell > 0.0)) { outCell = (cell > 0.0 ? cell : 1.0); outN = 1; return; } int n = static_cast(ext / cell) + 1; if (n <= kMaxVolumeDim) { outCell = cell; outN = (n < 1) ? 1 : n; return; } outN = kMaxVolumeDim; outCell = ext / static_cast(kMaxVolumeDim - 1); // maxDim 格覆盖全 ext } } // namespace BuiltVolume buildVolume(const PointSet& pts, double cellXY, double cellZ, double power, double maxDist) { if (pts.v.empty()) { throw std::invalid_argument("buildVolume: empty point set"); } // 1) 点集包络。 double minx = pts.x[0], maxx = pts.x[0]; double miny = pts.y[0], maxy = pts.y[0]; double minz = pts.z[0], maxz = pts.z[0]; for (std::size_t i = 1; i < pts.v.size(); ++i) { minx = std::min(minx, pts.x[i]); maxx = std::max(maxx, pts.x[i]); miny = std::min(miny, pts.y[i]); maxy = std::max(maxy, pts.y[i]); minz = std::min(minz, pts.z[i]); maxz = std::max(maxz, pts.z[i]); } // 2) GridSpec(角点对齐 = 原点取包络最小角)。间距优先用 cell;包络过大时放大间距以覆盖全程 // (fitAxis),避免跨 TM 多剖面相距过远时远端被截断。 GridSpec spec{}; spec.ox = minx; spec.oy = miny; spec.oz = minz; fitAxis(maxx - minx, cellXY, spec.dx, spec.nx); fitAxis(maxy - miny, cellXY, spec.dy, spec.ny); fitAxis(maxz - minz, cellZ, spec.dz, spec.nz); spec.power = power; spec.maxDist = maxDist; // 3) IDW(maxDist 外 NaN 留空)。 const IdwInterpolator idw; ScalarVolume vol = idw.interpolate(pts, spec); // 4) 数据实测值域(仅有限值)。无有限值 → 退化 {0,1}。 double vmin = std::numeric_limits::infinity(); double vmax = -std::numeric_limits::infinity(); for (double v : vol.data()) { if (std::isnan(v)) continue; vmin = std::min(vmin, v); vmax = std::max(vmax, v); } if (!(vmin < vmax)) { vmin = 0.0; vmax = 1.0; } return BuiltVolume{std::move(vol), spec, vmin, vmax}; } } // namespace geopro::core