/ concept-collection / hitandrun-interactive
Sign in
concept-collection / hitandrun-interactive
hitandrun-interactive / hitandrun_sampler.m
96 lines · 3.5 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);
28[sx, sy] = sample_region(vx, vy, N, convex);
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)
42% Figure -> script. Two requests the controls send:
d9d003fAdd non-convex (star) regions with a general hit-and-run samplerJeremy Magland 43% 'resample' {n, x, y, convex} -> draw n fresh samples in the given region;
44% reply with a 'samples' event.
45% 'newRegion' {n, convex} -> build a new region (convex or non-convex),
46% draw n samples; reply with a 'data' event.
9fbdc3eInteractive hit-and-run sampling of a 2D convex regionJeremy Magland 47d = ev.HTMLEventData;
48n = 10000;
50if isstruct(d)
51 if isfield(d, 'n')
52 n = max(1, round(d.n));
53 end
54 if isfield(d, 'convex')
55 convex = logical(d.convex);
56 end
58switch ev.HTMLEventName
59 case 'resample'
60 vx = d.x(:);
61 vy = d.y(:);
d9d003fAdd non-convex (star) regions with a general hit-and-run samplerJeremy Magland 62 [sx, sy] = sample_region(vx, vy, n, convex);
9fbdc3eInteractive hit-and-run sampling of a 2D convex regionJeremy Magland 63 sendEventToHTMLSource(src, 'samples', pack_samples(sx, sy, n));
64 case 'newRegion'
d9d003fAdd non-convex (star) regions with a general hit-and-run samplerJeremy Magland 65 [vx, vy] = make_region(convex);
66 [sx, sy] = sample_region(vx, vy, n, convex);
67 sendEventToHTMLSource(src, 'data', pack_data(vx, vy, sx, sy, n, convex));
68end
69end
71function [sx, sy] = sample_region(vx, vy, n, convex)
72% Convex regions use the fast JIT-compiled chord sampler; non-convex regions
73% use the general multi-segment sampler.
74tic;
75if convex
76 [sx, sy] = hit_and_run(vx, vy, n, 50);
77else
78 [sx, sy] = hit_and_run_general(vx, vy, n, 50);
d9d003fAdd non-convex (star) regions with a general hit-and-run samplerJeremy Magland 80fprintf('sample_region: N=%d convex=%d in %.3f s\n', n, convex, toc);
d9d003fAdd non-convex (star) regions with a general hit-and-run samplerJeremy Magland 83function data = pack_data(vx, vy, sx, sy, N, convex)
9fbdc3eInteractive hit-and-run sampling of a 2D convex regionJeremy Magland 84%PACK_DATA Full payload (region + samples) sent once when the figure opens.
85data = struct();
86data.type = 'hitandrun';
87data.region = struct('x', vx(:).', 'y', vy(:).');
88data.samples = struct('x', sx(:).', 'y', sy(:).');
89data.n = N;
93function s = pack_samples(sx, sy, N)
94%PACK_SAMPLES Just the samples, sent on a resample (region is unchanged).
95s = struct('x', sx(:).', 'y', sy(:).', 'n', N);
96end
moveopenescclose