mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-30 12:47:13 -06:00
Messhias is right that a sampled check cannot promise a run is straight, and my own write-up overstated what the grid did: I said the fit was "used only where it reproduces the real map", which five sample positions cannot establish. A bend narrower than the sample spacing passes between the samples, and the grid then approves an affine that is simply wrong. It is not a theoretical gap. A zigzag of amplitude 4 pt and half-period 20 pt, turning 11.3 degrees (under CORNER_DEG, so the vertices are not corners and their tangents blend flat), lands its y = 0 vertices exactly on the five sample positions. All 25 grid points then agree with the affine to the last digit while the art between them is thrown 4.000 pt off, against the 0.0613 pt tolerance the grid believed it was enforcing: 65 times over, measured, not estimated. `Track::is_straight(s0, s1)` reads the answer off the track instead. A bend in the span is two segment directions that differ, so no bend can hide in it whatever its size. It also checks the vertex tangents, because `frame` blends them across a segment unless the vertex is a corner, so a neighbour outside the span can bend the tangent inside it: directions alone would call `d, d, e` straight over the first two segments and be wrong. It fails closed on a closed track's seam, a non-finite bound and a track with no segments. `AlongMap::is_linear` covers the other half: Between Guides bends the arc-length map itself, which no amount of looking at the track would reveal. The grid stays, demoted to a second opinion that can reject and never admit, and `affine_fit`'s doc comment now says that rather than claiming to be the gate. Tests. `a_bend_shorter_than_the_sample_grid_is_still_a_bend` builds the zigzag above, asserts the sampled check accepts it, measures how far out the approved affine is, and then asserts the track-based gate refuses it; end to end through `bend` it asserts the aliased bend is subdivided while a genuinely straight run of the same span keeps the tile's four anchors. Restoring the sampled gate reds it with `the aliased bend is subdivided, not affine-mapped: 4 anchors`, so the old code really did lay a flat tile along a waving track. `straightness_is_read_off_the_track_not_sampled` covers the predicate directly: collinear segments and their extrapolation, a 0.2 pt detour, a span around it and a span before it, the blended-tangent case above, the closed seam and a NaN bound. Writing it caught a bug in my own guard: `f64::min` discards a NaN rather than propagating it, so `is_straight(NAN, 10.0)` was reporting straight until the finiteness check moved ahead of the min/max.