docs(visualizer): fix five inaccurate comments — sub-unity restitution, uniform heat boost, progressive push-out, scroll-speed cross-ref, eight-knob bar

This commit is contained in:
daniel-c-harvey
2026-06-17 05:20:12 -04:00
parent 4e34696719
commit d36aea212c
3 changed files with 13 additions and 11 deletions
@@ -59,7 +59,7 @@ public partial class MixWaveformVisualizer : ComponentBase, IAsyncDisposable
// `[MixVisualizer]`, same as the JS logs so the two interleave into one timeline). These pinpoint
// which upstream link is broken when the ribbon stays blank — set false once confirmed healthy.
// ON for the Phase 10 reframe Wave R4 controls test (matches the JS-side DEBUG in
// MixVisualizer.ts). Daniel evaluates the seven-knob bar + pause behavior in-browser; flip back to
// MixVisualizer.ts). Daniel evaluates the eight-knob bar + pause behavior in-browser; flip back to
// false at reframe close along with the JS flag.
private static readonly bool Debug = true;
private const string Tag = "[MixVisualizer]";
@@ -30,9 +30,10 @@ public sealed class MixVisualizerControlState
// sweet spot (§4c).
/// <summary>
/// Default scroll-speed dial. Mirrors <c>DEFAULT_SCROLL_SPEED</c> in MixVisualizer.ts. Normalized
/// [0,1] → mapped to the visible time-span via <see cref="MixZoomMapping"/> (0 = slow/wide window,
/// 1 = fast/tight window). Opens mid-range.
/// Default scroll-speed dial. Normalized [0,1] → mapped C#-side to a visible time-span in seconds
/// via <see cref="MixZoomMapping"/>, then sent to MixVisualizer.ts as a seconds value via
/// <c>setScrollSpeed</c>. The TS-side anchor is <c>DEFAULT_VISIBLE_SECONDS</c>. Opens mid-range
/// (0 = slow/wide window, 1 = fast/tight window).
/// </summary>
public const double DefaultScrollSpeed = 0.5;
@@ -1426,9 +1426,9 @@ export function create(canvas: HTMLCanvasElement): MixVisualizerHandle {
* toe) keeps the low end gentle so small dial moves near 0 don't suddenly erupt. */
function heatScaleFromDial(dial: number): number {
const d = Math.min(Math.max(dial, 0), 1);
// Smoothstep toe (gentle at 0) scaled to reach 1.2 at dial 1 — Phase 10 §3.4: ~20% stronger
// at the high end so full heat roils harder. The low/mid feel is unchanged (the toe dominates
// there); only the top end gains the extra 20% drive into the floor-heating + buoyancy + turbulence.
// Smoothstep toe (gentle at 0) scaled by 1.2 — Phase 10 §3.4: uniform +20% across the curve
// (every non-zero dial position is raised by 20%; the shape of the toe is preserved but the
// overall output is higher at every point).
return d * d * (3 - 2 * d) * 1.2;
}
@@ -1601,7 +1601,8 @@ export function create(canvas: HTMLCanvasElement): MixVisualizerHandle {
b.vx += sideSign * WAVE_COLLIDE_SPRING * penetration * dt * (1 - collideHardness);
// Hard elastic reflection (hard end): bounce the inward velocity back out, scaled
// by restitution × hardness (over-unity restitution at the top = the springy throw).
// by restitution × hardness. Restitution is sub-unity (≤ 0.85) — bounded reflection,
// no energy added.
if (inwardSpeed > 0) {
b.vx += sideSign * inwardSpeed * (1 + waveRest) * collideHardness;
}
@@ -1613,9 +1614,9 @@ export function create(canvas: HTMLCanvasElement): MixVisualizerHandle {
const throwUp = Math.min(WAVE_THROW_UP * penetration * dt * collideHardness, WAVE_THROW_UP_MAX);
b.vy -= throwUp;
// Positional push-out: always eject the wax fully out of the ribbon along the normal so
// it can never lodge inside (Daniel "gets stuck"). The soft end eases it out gently
// (mushy), the hard end snaps it clean — but both clear the boundary, so no stuck wax.
// Positional push-out: ejects the wax progressively out of the ribbon along the normal
// (converges across substeps, so no stuck wax). The soft end eases it out gently
// (mushy), the hard end snaps it clean.
b.x += sideSign * penetration * (0.5 + 0.5 * collideHardness);
}