fix: a zoomed trace is drawn on the x its readout quotes
gather() staged x as f32 relative to the series' own x0() -- the start of the whole retained window -- so the quantisation was a fraction of the ring rather than of the view: 1.9 us at 20 s of retained data, which at a 10 us view across a 716 px axis is over 100 px between where a sample is drawn and the x a readout quotes for it (crosshair_point() reads x_at() in exact f64). It halved on every zoom out, which is what made it read as "zooming in makes the crosshair select a point beside the data". The origin is now the caller's (plotter c2c8c59): the renderer passes the visible range's minimum, so the error is a fixed 2^-24 of what is on screen -- about 4e-5 px over a 700 px axis -- at any zoom. The parameter sits before out_xy so every call site is a compile error rather than a silent change of behaviour. The renderer no longer reads series.x0() at paint time at all, which removes two of the three symptoms of the torn window_x0_ read by construction; the ink probe's now-vacuous kept_fixed_x0 walk goes with them, replaced by a drawn-vs-quoted pixel figure. neighbours() still tests the visible range against x_at(0), so the cache stays load-bearing. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
39f30d913f
commit
2f4530c128
7 files changed
+176
-90
No files matched your search
+5
-5
@@ -189,7 +189,7 @@ void ChannelBuffer::raw(u64 begin, u64 end, f32* out) const {
|
||||
for (u64 i = count; i < end - begin; ++i) out[i] = 0.0f;
|
||||
}
|
||||
|
||||
void ChannelBuffer::gather(u32 level, u64 begin, u64 end, std::vector<f32>& out_xy,
|
||||
void ChannelBuffer::gather(u32 level, u64 begin, u64 end, f64 x_origin, std::vector<f32>& out_xy,
|
||||
plot::data::GatherMode mode) const {
|
||||
const u64 n = pyramid_.size();
|
||||
const u64 b = std::min(begin, n);
|
||||
@@ -197,7 +197,7 @@ void ChannelBuffer::gather(u32 level, u64 begin, u64 end, std::vector<f32>& out_
|
||||
if (b >= e) return;
|
||||
|
||||
const u64 origin = pyramid_.window_base();
|
||||
const f64 base = x0(); // x is emitted relative to this (see the header)
|
||||
const f64 base = x_origin; // x is emitted relative to this (see the header)
|
||||
|
||||
const auto emit_raw = [&](u64 from, u64 to) {
|
||||
for (u64 i = from; i < to; ++i) {
|
||||
@@ -302,13 +302,13 @@ u64 SlotSeries::snap_index(f64 x) const {
|
||||
return buffer_ != nullptr ? buffer_->snap_index(x) : 0;
|
||||
}
|
||||
|
||||
void SlotSeries::gather(u32 level, u64 begin, u64 end, std::vector<f32>& out_xy,
|
||||
void SlotSeries::gather(u32 level, u64 begin, u64 end, f64 x_origin, std::vector<f32>& out_xy,
|
||||
plot::data::GatherMode mode) const {
|
||||
if (event_ != nullptr) {
|
||||
event_->gather(level, begin, end, out_xy, mode);
|
||||
event_->gather(level, begin, end, x_origin, out_xy, mode);
|
||||
return;
|
||||
}
|
||||
if (buffer_ != nullptr) buffer_->gather(level, begin, end, out_xy, mode);
|
||||
if (buffer_ != nullptr) buffer_->gather(level, begin, end, x_origin, out_xy, mode);
|
||||
}
|
||||
|
||||
void SlotSeries::copy_raw(u64 begin, u64 end, f32* out) const {
|
||||
|
||||
Reference in new issue
Block a user