40#ifndef MESH_PROFILE_INTERP_H
41#define MESH_PROFILE_INTERP_H
70 const QVector<MeshProfileSampler::Sample> &
s,
73 const int n =
s.size();
74 const double kNaN = std::numeric_limits<double>::quiet_NaN();
75 QVector<double> top(
n, kNaN);
78 for (
int i = 0;
i <
n; ++
i) {
79 if (!std::isfinite(
s[
i].ground))
continue;
80 const double t = topElev(
s[
i]);
87 if (std::isnan(top[
i])) { ++
i;
continue; }
91 while (runEnd + 1 <
n && !std::isnan(top[runEnd + 1])) ++runEnd;
97 const int gapStart = runEnd + 1;
100 bool sawNoData =
false;
101 while (next <
n && std::isnan(top[next])) {
102 if (!std::isfinite(
s[next].ground)) { blocked =
true;
break; }
103 if (!
s[next].cellHasSurface) sawNoData =
true;
107 if (!blocked && sawNoData && next <
n && gapStart < next) {
108 const double cL =
s[runEnd].chainage, wseL = top[runEnd];
109 const double cR =
s[next].chainage, wseR = top[next];
110 const double dC = cR - cL;
111 const double wseUp = std::max(wseL, wseR);
112 for (
int k = gapStart;
k < next; ++
k) {
113 if (!std::isfinite(
s[
k].ground))
continue;
114 double wse = (dC > 1
e-12)
115 ? wseL + (
s[
k].chainage - cL) / dC * (wseR - wseL)
117 if (wse > wseUp) wse = wseUp;
124 i = blocked ? (runEnd + 1) : std::max(next, runEnd + 1);
163 const QVector<double> &top,
164 int runFirst,
int runLast,
bool trailing,
165 double *outChainage,
double *outElev)
167 const int n =
s.size();
168 if (runFirst < 0 || runLast >=
n || runFirst > runLast || top.size() !=
n)
170 const int i = trailing ? runLast : runFirst;
171 const int j = trailing ? runLast - 1 : runFirst + 1;
172 const int k = trailing ? runLast + 1 : runFirst - 1;
173 if (k < 0 || k >=
n)
return false;
174 if (!std::isfinite(
s[
k].ground))
return false;
175 if (!std::isnan(top[
k]))
return false;
176 if (std::isnan(top[
i]) || !std::isfinite(
s[
i].ground))
return false;
178 const double ci =
s[
i].chainage, ck =
s[
k].chainage;
179 const double dSeg = ck - ci;
180 if (std::abs(dSeg) < 1
e-12)
return false;
185 if (j >= runFirst && j <= runLast) {
186 const double dcw = ci -
s[j].chainage;
187 if (std::abs(dcw) > 1
e-12 && !std::isnan(top[j]))
188 mTop = (top[
i] - top[j]) / dcw;
195 const double gi =
s[
i].ground, gk =
s[
k].ground;
196 const double denom = (gk - gi) - mTop * dSeg;
197 if (denom <= 1
e-12)
return false;
198 const double t = (top[
i] - gi) / denom;
199 if (t <= 0.0 || t > 1.0)
return false;
201 if (outChainage) *outChainage = ci +
t * dSeg;
202 if (outElev) *outElev = gi +
t * (gk - gi);
size_t i
Definition contourjob.cpp:27
DiagramType t
Definition diagramspec.cpp:20
double s
Scene px per model length unit.
Definition inletdrawingview.cpp:82
int e
Definition inpmeshreader.cpp:41
std::size_t n
Definition mesh2dresultsexport.cpp:426
int k
Definition mesh2dresultsexport.cpp:549
Pure-logic sampler that turns a user-traced polyline across the 2D surface mesh into a longitudinal c...
Definition meshprofileinterp.h:52
QVector< double > bridgedTops(const QVector< MeshProfileSampler::Sample > &s, const std::function< double(const MeshProfileSampler::Sample &)> &topElev)
Compute the per-sample water-surface elevation to paint for one wet-band pass, with shallow-film rend...
Definition meshprofileinterp.h:69
bool shorelineIntercept(const QVector< MeshProfileSampler::Sample > &s, const QVector< double > &top, int runFirst, int runLast, bool trailing, double *outChainage, double *outElev)
Shoreline intercept just outside one end of a wet run — the exact chainage where the (wet-side-extrap...
Definition meshprofileinterp.h:162
constexpr double kFilm
Definition meshprofileinterp.h:58
One point along the traced cross-section.
Definition profilesection.h:37