Generate convex region without convhull (fixes figure-view startup race)
The figure-only view auto-runs the script on worker startup, before the qhull
WASM backend finishes loading, so convhull threw 'backend not initialized'.
Build the convex region as vertices at sorted angles on a random ellipse
instead — convex by construction, no backend needed.
2 changed files+16−12
CLAUDE.mdmodified+1−1View file
@@ -86,7 +86,7 @@ or a "uniform vs. non-uniform target" toggle.
8686 | `app/src/render/RegionView.tsx` | 2D canvas renderer (region outline + sample dots + movie `segments`) |
8787 | `app/src/bridge.ts` | `onData` / `onHostEvent` / `sendToMATLAB` helpers (generic; identical across these projects) |
8888 | `hitandrun_sampler.m` | Opens the figure, sends data, handles `resample`/`newRegion` (figure plumbing: `on_event`, `sample_region`, `pack_data`, `pack_samples`) |
89-| `helpers/make_region.m` | Random region — convex hull of disk points, or `make_region(false)` for a star polygon |
89+| `helpers/make_region.m` | Random region — convex polygon on an ellipse (no convhull, so the auto-running figure view doesn't race the qhull backend load), or `make_region(false)` for a star polygon |
9090 | `helpers/hit_and_run.m` | Convex hit-and-run sampler (half-plane chord intersection; JIT) |
9191 | `helpers/hit_and_run_general.m` | Non-convex hit-and-run sampler (all in-region segments; interpreter) |
9292 | `hitandrun_demo.m` | User-facing driver: `addpath('helpers')` + seed + call the sampler |
helpers/make_region.mmodified+15−11View file
@@ -1,6 +1,6 @@
11 function [vx, vy] = make_region(convex)
22 %MAKE_REGION Random 2D sampling region, returned as CCW vertices (VX, VY).
3-% MAKE_REGION(true) — a convex polygon (convex hull of random disk points).
3+% MAKE_REGION(true) — a convex polygon (vertices on a random ellipse).
44 % MAKE_REGION(false) — a non-convex star polygon (star-shaped about the
55 % origin, so the origin is a valid interior start point).
66 if nargin < 1 || isempty(convex)
@@ -21,16 +21,20 @@ end
2121 end
2222
2323 function [vx, vy] = convex_region()
24-% Convex hull of random points in a disk; anisotropic scaling for variety.
25-m = 12;
26-ang = 2 * pi * rand(m, 1);
27-r = sqrt(rand(m, 1));
28-px = 1.4 * r .* cos(ang);
29-py = 1.0 * r .* sin(ang);
30-k = convhull(px, py);
31-k = k(1:end-1);
32-vx = px(k);
33-vy = py(k);
24+% Vertices at increasing angles on an anisotropic, randomly rotated ellipse.
25+% Points taken in angular order on the ellipse are always in convex position,
26+% so the polygon is convex by construction — no convhull backend needed (the
27+% browser worker may not have finished loading it when the figure view
28+% auto-runs the script). Even angular slots + bounded jitter keep the angles
29+% ordered and the edges non-degenerate while still random.
30+m = 6 + randi(4); % 7..10 vertices
31+slot = 2 * pi / m;
32+ang = (0:m - 1).' * slot + (rand(m, 1) - 0.5) * slot * 0.8;
33+ex = 1.4 * cos(ang); % on an ellipse (anisotropic)
34+ey = 1.0 * sin(ang);
35+phi = 2 * pi * rand; % random orientation
36+vx = cos(phi) * ex - sin(phi) * ey;
37+vy = sin(phi) * ex + cos(phi) * ey;
3438 end
3539
3640 function [vx, vy] = star_region()