pub fn miter_extension(
width: f32,
prev: [f32; 2],
vertex: [f32; 2],
next: [f32; 2],
) -> f32Expand description
The extension a joined end needs to reach its corner’s point: the miter
length at vertex, where the chain arrives from prev and leaves for
next, clamped to MITER_LIMIT half-widths (ADR-0158).
§The expression, and why it carries no trigonometry
For an interior angle theta the miter is width / sin(theta / 2). Writing
d1, d2 for the two unit directions, the turn between them is
theta_turn = pi - theta, so
sin(theta / 2) = cos(theta_turn / 2) = sqrt((1 + d1 · d2) / 2)— a dot product and a square root, with no acos to lose precision near the
straight case and no branch on the turn’s sign. A straight joint has
d1 · d2 = 1 and yields exactly width, which is the flat half-width, so a
collinear chain is byte-identical to one that extends by width.
§Homogeneous of degree 1 in width
Both width / sin(theta / 2) and the clamp MITER_LIMIT * width scale
linearly, so miter(c * w) == c * miter(w) and the clamp cannot be engaged
at one width and not another. That is what lets the cached producers compute
this against PLACEHOLDER_WIDTH at configure and have
LineInstance::styled carry it to this frame’s width by the ratio. Both are
crate-private, so this names them rather than linking them. theta survives
that too: every transform between a producer and the shader — uniform scale,
rotation, reflection, the mirror replication, normalize_fit — is a
similarity, and a similarity preserves angles.
§Degenerate input
A zero-length arm has no direction, and a chain that doubles back exactly
(d1 · d2 = -1) has no reachable point. Both fall back to width, the flat
half-width — which is the same value a corner past MITER_LIMIT takes, so
the degenerate case is the limit case rather than a separate rule.