9fbdc3eInteractive hit-and-run sampling of a 2D convex regionJeremy Magland 1# Interactive hit-and-run sampling
3Runs in the browser via [numbl](https://numbl.org) — no install.
67636f7Add figure-only view (#figure/sampler)Jeremy Magland 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.
9fbdc3eInteractive hit-and-run sampling of a 2D convex regionJeremy Magland 11## ▶ [Open `hitandrun_demo.m`](hitandrun_demo.m) and click **Run**
d9d003fAdd non-convex (star) regions with a general hit-and-run samplerJeremy Magland 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,
76fb400Non-convex region: replace star polygon with a two-bulb dumbbellJeremy Magland 17but you can switch to a non-convex **dumbbell** — two convex bulbs joined by a
18narrow tube — where a single line can enter and leave the region more than once.
20Controls:
22- **Samples** — set `N` (re-runs the sampler).
23- **Resample** — new samples, same region.
d9d003fAdd non-convex (star) regions with a general hit-and-run samplerJeremy Magland 24- **New region** — a fresh region (of the current type).
76fb400Non-convex region: replace star polygon with a two-bulb dumbbellJeremy Magland 25- **non-convex region** — toggle between a convex region and the non-convex
26 dumbbell. The non-convex region uses the slower general sampler, so `N` is
27 capped lower.
a50c671Non-convex: add local-segment vs. union sampling modeJeremy Magland 28- **local segment only** *(non-convex only)* — by default the step samples
29 across *every* segment where the line crosses the region (the standard walk,
30 uniform on the whole region); check this to instead sample only within the
76fb400Non-convex region: replace star polygon with a two-bulb dumbbellJeremy Magland 31 segment that contains the current point — a local walk that can't jump across
32 the gap between two bulbs, so it does not sample uniformly.
d9d003fAdd non-convex (star) regions with a general hit-and-run samplerJeremy Magland 33- **Play movie** — step through the algorithm: each step draws the chord — one
a50c671Non-convex: add local-segment vs. union sampling modeJeremy Magland 34 segment for a convex region, possibly several for a non-convex one (or just
35 the local segment) — and the point that landed on it.
37## How it works
39- [`hitandrun_demo.m`](hitandrun_demo.m) — driver: `addpath('helpers')`, seed, call the sampler.
d9d003fAdd non-convex (star) regions with a general hit-and-run samplerJeremy Magland 40- [`hitandrun_sampler.m`](hitandrun_sampler.m) — opens the figure, sends data, handles resample requests, and dispatches to the convex or non-convex sampler.
76fb400Non-convex region: replace star polygon with a two-bulb dumbbellJeremy Magland 41- `helpers/` — [`make_region.m`](helpers/make_region.m) (convex ellipse or dumbbell 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).
9fbdc3eInteractive hit-and-run sampling of a 2D convex regionJeremy Magland 42- `app/` — a single-file React app that draws the region and samples on a canvas.
44The script and figure talk both ways: the script sends the region + samples via
45`uihtml(..., 'Data', ...)`, and the controls call back with
d9d003fAdd non-convex (star) regions with a general hit-and-run samplerJeremy Magland 46`sendToMATLAB('resample' | 'newRegion', ...)` (each carrying whether the region
a50c671Non-convex: add local-segment vs. union sampling modeJeremy Magland 47is `convex` and, for non-convex, the `local` sampling mode), which re-runs the
48sampler and returns new points via `sendEventToHTMLSource`. The script is
49stateless — the figure owns the region and passes it back with each request.
d9d003fAdd non-convex (star) regions with a general hit-and-run samplerJeremy Magland 51## Convex vs. non-convex
d9d003fAdd non-convex (star) regions with a general hit-and-run samplerJeremy Magland 53`hitandrun_sampler.m` picks the sampler by region type:
55- **Convex** — [`hit_and_run.m`](helpers/hit_and_run.m) takes the single chord
56 where the line crosses the region (an inward-half-plane intersection). Its
57 loop runs once per sample, so numbl JS-JIT-compiles it to JavaScript — about
58 30× faster than its interpreter, which is what keeps large `N` instant. The
59 `%!numbl:assert_jit` directive asserts this happens (it errors rather than
60 silently falling back). It relies on numbl's scalar-`rand()` JIT support;
61 `rng(seed)` still controls the shared PRNG.
62- **Non-convex** — [`hit_and_run_general.m`](helpers/hit_and_run_general.m)
a50c671Non-convex: add local-segment vs. union sampling modeJeremy Magland 63 finds *every* crossing along the line and keeps the in-region segments (a
64 point-in-polygon test on each interval's midpoint), so concavities are handled
65 correctly. It then samples in one of two modes: **union** (default) picks a
66 point uniformly across all those segments, which samples the whole region
67 uniformly; **local** (the *local segment only* checkbox) restricts to the
76fb400Non-convex region: replace star polygon with a two-bulb dumbbellJeremy Magland 68 single segment straddling the current point — a local walk that can't jump the
69 gap between the two bulbs, so it does *not* sample uniformly. The sort +
70 polygon tests don't JIT, so this runs in the interpreter and `N` is capped
71 lower. `make_region(false)` builds the dumbbell, which is not star-shaped and
72 need not contain the origin, so the sampler finds an interior start by
73 rejection rather than assuming one.
75## Deploy
77Pushing to `main` builds the app and publishes the project to GitHub Pages via
78the [deploy workflow](.github/workflows/deploy.yml).