54std::size_t seek(
const X& x, std::size_t n, std::size_t from,
double v)
82 std::size_t n,
const X& x,
const Y& y,
const MinMaxPyramid& pyramid,
83 std::size_t pyramid_offset,
double x0,
double x1,
int columns,
84 std::vector<QPointF>& out)
87 if(n == 0 || columns <= 0 || !(x1 > x0))
90 const std::size_t begin = detail::seek(x, n, 0, x0);
91 const std::size_t end = std::min(n, detail::seek(x, n, begin, x1) + 1);
93 out.emplace_back(x(begin - 1), y(begin - 1));
95 const double width = (x1 - x0) / columns;
96 std::size_t i = begin;
97 for(
int c = 0; c < columns && i < end; c++)
99 const double col_end = c + 1 == columns ? x1 : x0 + (c + 1) * width;
100 const std::size_t j = std::min(end, detail::seek(x, n, i, col_end));
103 for(std::size_t k = i; k < j; k++)
104 out.emplace_back(x(k), y(k));
108 const auto [lo, hi] = pyramid.
range(pyramid_offset + i, pyramid_offset + j);
109 const double first = y(i), last = y(j - 1);
110 const double mid = x0 + (c + 0.5) * width;
111 out.emplace_back(x(i), first);
115 out.emplace_back(mid, lo);
116 out.emplace_back(mid, hi);
120 out.emplace_back(mid, hi);
121 out.emplace_back(mid, lo);
123 out.emplace_back(x(j - 1), last);
128 out.emplace_back(x(i), y(i));
130 out.emplace_back(x(end), y(end));
139 std::size_t n,
const X& x,
const Y& y,
const MinMaxPyramid& pyramid,
140 std::size_t pyramid_offset,
double x0,
double width,
int columns,
141 std::vector<QLineF>& out)
144 if(n == 0 || columns <= 0 || !(width > 0.))
146 out.reserve(columns);
149 auto at = [&](std::size_t k,
double v) {
150 const double xa = x(k - 1), xb = x(k);
151 const double t = xb > xa ? (v - xa) / (xb - xa) : 1.;
152 return y(k - 1) + t * (y(k) - y(k - 1));
155 std::size_t i = detail::seek(x, n, 0, x0);
156 for(
int c = 0; c < columns; c++)
158 const double a = x0 + c * width;
159 const double b = a + width;
160 const double mid = a + 0.5 * width;
161 const std::size_t j = detail::seek(x, n, i, b);
163 double lo = std::numeric_limits<double>::max();
164 double hi = std::numeric_limits<double>::lowest();
166 std::tie(lo, hi) = pyramid.
range(pyramid_offset + i, pyramid_offset + j);
169 const double v = at(i, a);
170 lo = std::min(lo, v);
171 hi = std::max(hi, v);
175 const double v = at(j, b);
176 lo = std::min(lo, v);
177 hi = std::max(hi, v);
180 out.emplace_back(mid, lo, mid, hi);
std::pair< float, float > range(std::size_t first, std::size_t last) const noexcept
Over [first, last), which must not be empty.
Definition Envelope.cpp:40
void envelope(std::size_t n, const X &x, const Y &y, const MinMaxPyramid &pyramid, std::size_t pyramid_offset, double x0, double x1, int columns, std::vector< QPointF > &out)
Definition score-plugin-curve/Curve/Envelope.hpp:81
void envelopeColumns(std::size_t n, const X &x, const Y &y, const MinMaxPyramid &pyramid, std::size_t pyramid_offset, double x0, double width, int columns, std::vector< QLineF > &out)
Definition score-plugin-curve/Curve/Envelope.hpp:138