MCPcopy Create free account
hub / github.com/Serial-Studio/Serial-Studio / downsampleMonotonic

Function downsampleMonotonic

app/src/DSP.h:1081–1135  ·  view source on GitHub ↗

* @brief Downsample a 2D series (X,Y) into screen-space pixels, preserving extremes. * X must be monotonic non-decreasing: the X bounds come from the finite * endpoints and the Y bounds from the filled columns, so the samples are * walked once (bucket accumulation) instead of twice. */

Source from the content-addressed store, hash-verified

1079 * walked once (bucket accumulation) instead of twice.
1080 */
1081inline bool downsampleMonotonic(
1082 const AxisData& X, const AxisData& Y, int w, int h, QList<QPointF>& out, DownsampleWorkspace* ws)
1083{
1084 out.clear();
1085 const std::size_t n = std::min<std::size_t>(X.size(), Y.size());
1086 if (n == 0 || w <= 0 || h <= 0)
1087 return true;
1088
1089 std::size_t xn0, xn1, yn0, yn1;
1090 const ssfp_t *xp0, *xp1, *yp0, *yp1;
1091 spanFromFixedQueue(X, xp0, xn0, xp1, xn1);
1092 spanFromFixedQueue(Y, yp0, yn0, yp1, yn1);
1093
1094 auto xAt = [&](std::size_t i) -> ssfp_t {
1095 return (i < xn0) ? xp0[i] : xp1[i - xn0];
1096 };
1097 auto yAt = [&](std::size_t i) -> ssfp_t {
1098 return (i < yn0) ? yp0[i] : yp1[i - yn0];
1099 };
1100
1101 std::size_t firstFinite = 0;
1102 std::size_t lastFinite = 0;
1103 if (!dsFiniteEnds(n, xAt, yAt, firstFinite, lastFinite))
1104 return false;
1105
1106 const ssfp_t xmin = xAt(firstFinite);
1107 const ssfp_t xmax = xAt(lastFinite);
1108 if (!(xmin < xmax)) {
1109 dsEmitSteppedFallback(n, w, firstFinite, lastFinite, xAt, yAt, out);
1110 return true;
1111 }
1112
1113 const std::size_t C = std::size_t(w);
1114 ws->reset(C);
1115
1116 const auto scaleX = static_cast<ssfp_t>(w - 1) / std::max(1e-12, xmax - xmin);
1117 dsAccumulateBuckets(n, w, xmin, scaleX, xAt, yAt, ws);
1118
1119 ssfp_t ymin = 0;
1120 ssfp_t ymax = 0;
1121 if (!dsColumnYBounds(ws, C, ymin, ymax))
1122 return false;
1123
1124 const auto scaleY = static_cast<ssfp_t>(h) / std::max(1e-12, ymax - ymin);
1125
1126 out.reserve(w * 3 / 2 + 8);
1127 for (std::size_t c = 0; c < C; ++c) {
1128 if (ws->cnt[c] == 0)
1129 continue;
1130
1131 dsEmitColumnPoints(c, scaleY, ws, xAt, yAt, out);
1132 }
1133
1134 return true;
1135}
1136
1137/**
1138 * @brief Downsample a LineSeries (paired X and Y AxisData) for rendering.

Callers 3

updateDataMethod · 0.85
updateDataMethod · 0.85
updateDataMethod · 0.85

Calls 9

spanFromFixedQueueFunction · 0.85
dsFiniteEndsFunction · 0.85
dsEmitSteppedFallbackFunction · 0.85
dsAccumulateBucketsFunction · 0.85
dsColumnYBoundsFunction · 0.85
dsEmitColumnPointsFunction · 0.85
clearMethod · 0.45
sizeMethod · 0.45
resetMethod · 0.45

Tested by

no test coverage detected