1# Interactive hit-and-run sampling
3Runs in the browser via [numbl](https://numbl.org) β no install.
5## π [Just the figure β](https://concept-collection.github.io/hitandrun-interactive/#figure/sampler)
7The figure-only view runs the sampler and drops you straight into the
8interactive figure (it shows the run's output first, then the figure). The full
9developer view β file tree, editable code, console β is below.
11## βΆ [Open `hitandrun_demo.m`](hitandrun_demo.m) and click **Run**
13A random 2D region is generated and `N` points are drawn uniformly from it by
14**hit-and-run**: from the current point, pick a random direction, take the chord
15where that line crosses the region, and jump to a uniform point on it. Repeat.
16The figure shows the region and the samples. The region is convex by default,
17but you can switch to a non-convex (star-shaped) one, where a single line can
18enter and leave the region several times.
20Controls:
22- **Samples** β set `N` (re-runs the sampler).
23- **Resample** β new samples, same region.
24- **New region** β a fresh region (of the current type).
25- **non-convex region** β toggle between a convex region and a non-convex
26 star-shaped one. The non-convex region uses the slower general sampler, so
27 `N` is capped lower.
28- **Play movie** β step through the algorithm: each step draws the chord β one
29 segment for a convex region, possibly several for a non-convex one β and the
30 point that landed on it.
32## How it works
34- [`hitandrun_demo.m`](hitandrun_demo.m) β driver: `addpath('helpers')`, seed, call the sampler.
35- [`hitandrun_sampler.m`](hitandrun_sampler.m) β opens the figure, sends data, handles resample requests, and dispatches to the convex or non-convex sampler.
36- `helpers/` β [`make_region.m`](helpers/make_region.m) (convex or star region), [`hit_and_run.m`](helpers/hit_and_run.m) (convex chord), and [`hit_and_run_general.m`](helpers/hit_and_run_general.m) (arbitrary simple polygon).
37- `app/` β a single-file React app that draws the region and samples on a canvas.
39The script and figure talk both ways: the script sends the region + samples via
40`uihtml(..., 'Data', ...)`, and the controls call back with
41`sendToMATLAB('resample' | 'newRegion', ...)` (each carrying whether the region
42is `convex`), which re-runs the sampler and returns new points via
43`sendEventToHTMLSource`. The script is stateless β the figure owns the region
44and passes it back with each request.
46## Convex vs. non-convex
48`hitandrun_sampler.m` picks the sampler by region type:
50- **Convex** β [`hit_and_run.m`](helpers/hit_and_run.m) takes the single chord
51 where the line crosses the region (an inward-half-plane intersection). Its
52 loop runs once per sample, so numbl JS-JIT-compiles it to JavaScript β about
53 30Γ faster than its interpreter, which is what keeps large `N` instant. The
54 `%!numbl:assert_jit` directive asserts this happens (it errors rather than
55 silently falling back). It relies on numbl's scalar-`rand()` JIT support;
56 `rng(seed)` still controls the shared PRNG.
57- **Non-convex** β [`hit_and_run_general.m`](helpers/hit_and_run_general.m)
58 finds *every* crossing along the line, keeps the segments whose midpoint is
59 inside (a point-in-polygon test), and samples uniformly across their union, so
60 concavities are handled correctly. The sort + polygon tests don't JIT, so this
61 runs in the interpreter and `N` is capped lower. `make_region(false)` builds a
62 star polygon that is star-shaped about the origin, so the origin is a valid
63 interior start point.
65## Deploy
67Pushing to `main` builds the app and publishes the project to GitHub Pages via
68the [deploy workflow](.github/workflows/deploy.yml).