/ concept-collection / hitandrun-interactive
Sign in
concept-collection / hitandrun-interactive
hitandrun-interactive / hitandrun_sampler.m
102 lines · 3.8 KBCodeBlameHistory
9fbdc3eInteractive hit-and-run sampling of a 2D convex regionJeremy Magland 1function hitandrun_sampler(N)
2%HITANDRUN_SAMPLER Interactive figure: hit-and-run sampling of a 2D convex region.
3% HITANDRUN_SAMPLER(N) generates a random convex polygon, draws N samples
4% from the uniform distribution on it using the hit-and-run algorithm, and
5% opens a figure that shows the region and the samples.
6%
7% This holds all the wiring: it builds the region, runs the sampler, loads
8% the prebuilt figure app, and sends region + samples to it (script ->
9% figure). It also re-samples on request (figure -> script) so the controls
10% in the figure drive the algorithm.
12% The region/sampling algorithm lives in helpers/ (make_region, hit_and_run);
13% the end-user script (hitandrun_demo.m) puts that folder on the path with
14% `addpath('helpers')` and calls this. Run hitandrun_demo.m, not this file
15% directly, so the path is set up.
17% The script is a stateless sampling service: the figure owns the current
18% region and sends it back with each resample request, so there is no
19% server-side state to keep in sync across callbacks.
21if nargin < 1 || isempty(N)
d9d003fAdd non-convex (star) regions with a general hit-and-run samplerJeremy Magland 25% Build a region (convex by default) and draw N uniform samples from it.
26convex = true;
27[vx, vy] = make_region(convex);
a50c671Non-convex: add local-segment vs. union sampling modeJeremy Magland 28[sx, sy] = sample_region(vx, vy, N, convex, false);
30% The figure app is the prebuilt single-file page, relative to the project root
31% (the current working directory when a top-level script is run).
32html = fileread(fullfile('app', 'dist', 'index.html'));
34fig = figure;
35gl = uigridlayout(fig, [1 1], 'Padding', [0 0 0 0], ...
36 'RowHeight', {'1x'}, 'ColumnWidth', {'1x'});
d9d003fAdd non-convex (star) regions with a general hit-and-run samplerJeremy Magland 37uihtml(gl, 'HTMLSource', html, 'Data', pack_data(vx, vy, sx, sy, N, convex), ...
9fbdc3eInteractive hit-and-run sampling of a 2D convex regionJeremy Magland 38 'HTMLEventReceivedFcn', @(src, ev) on_event(src, ev));
39end
41function on_event(src, ev)
a50c671Non-convex: add local-segment vs. union sampling modeJeremy Magland 42% Figure -> script. Two requests the controls send (both carry the region type
43% `convex` and, for non-convex regions, the `local` sampling mode):
44% 'resample' {n, x, y, convex, local} -> draw n fresh samples in the given
45% region; reply with a 'samples' event.
46% 'newRegion' {n, convex, local} -> build a new region (convex or
47% non-convex), draw n samples; reply with a
48% 'data' event.
9fbdc3eInteractive hit-and-run sampling of a 2D convex regionJeremy Magland 49d = ev.HTMLEventData;
50n = 10000;
54 if isfield(d, 'n')
55 n = max(1, round(d.n));
56 end
57 if isfield(d, 'convex')
58 convex = logical(d.convex);
59 end
a50c671Non-convex: add local-segment vs. union sampling modeJeremy Magland 60 if isfield(d, 'local')
61 local = logical(d.local);
62 end
64switch ev.HTMLEventName
65 case 'resample'
66 vx = d.x(:);
67 vy = d.y(:);
a50c671Non-convex: add local-segment vs. union sampling modeJeremy Magland 68 [sx, sy] = sample_region(vx, vy, n, convex, local);
9fbdc3eInteractive hit-and-run sampling of a 2D convex regionJeremy Magland 69 sendEventToHTMLSource(src, 'samples', pack_samples(sx, sy, n));
70 case 'newRegion'
d9d003fAdd non-convex (star) regions with a general hit-and-run samplerJeremy Magland 71 [vx, vy] = make_region(convex);
a50c671Non-convex: add local-segment vs. union sampling modeJeremy Magland 72 [sx, sy] = sample_region(vx, vy, n, convex, local);
d9d003fAdd non-convex (star) regions with a general hit-and-run samplerJeremy Magland 73 sendEventToHTMLSource(src, 'data', pack_data(vx, vy, sx, sy, n, convex));
74end
75end
a50c671Non-convex: add local-segment vs. union sampling modeJeremy Magland 77function [sx, sy] = sample_region(vx, vy, n, convex, local)
d9d003fAdd non-convex (star) regions with a general hit-and-run samplerJeremy Magland 78% Convex regions use the fast JIT-compiled chord sampler; non-convex regions
a50c671Non-convex: add local-segment vs. union sampling modeJeremy Magland 79% use the general sampler, in union (default) or local-segment mode.
81if convex
82 [sx, sy] = hit_and_run(vx, vy, n, 50);
83else
a50c671Non-convex: add local-segment vs. union sampling modeJeremy Magland 84 [sx, sy] = hit_and_run_general(vx, vy, n, 50, local);
a50c671Non-convex: add local-segment vs. union sampling modeJeremy Magland 86fprintf('sample_region: N=%d convex=%d local=%d in %.3f s\n', n, convex, local, toc);
d9d003fAdd non-convex (star) regions with a general hit-and-run samplerJeremy Magland 89function data = pack_data(vx, vy, sx, sy, N, convex)
9fbdc3eInteractive hit-and-run sampling of a 2D convex regionJeremy Magland 90%PACK_DATA Full payload (region + samples) sent once when the figure opens.
91data = struct();
92data.type = 'hitandrun';
93data.region = struct('x', vx(:).', 'y', vy(:).');
94data.samples = struct('x', sx(:).', 'y', sy(:).');
95data.n = N;
99function s = pack_samples(sx, sy, N)
100%PACK_SAMPLES Just the samples, sent on a resample (region is unchanged).
101s = struct('x', sx(:).', 'y', sy(:).', 'n', N);
102end
moveopenescclose