@descix/frqtl-node 0.6.0-p0.2 → 0.6.0-p4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +2 -2
- package/README.md +8 -4
- package/dist/dist-manifest.json +70 -62
- package/dist/eyes/index.js +5 -2
- package/dist/frqtl/assets/vendor/acorn.LICENSE +21 -0
- package/dist/frqtl/assets/vendor/acorn.PINNED.json +9 -0
- package/dist/frqtl/assets/vendor/acorn.mjs +6266 -0
- package/dist/frqtl/compat/renderer/lo-drawn-center.js +41 -0
- package/dist/frqtl/experiments/_shared/boot-failure.js +60 -0
- package/dist/frqtl/objects/FrqtlApp.js +136 -30
- package/dist/frqtl/objects/ObjectFactory.js +4 -5
- package/dist/frqtl/objects/RecipeContext.js +617 -9
- package/dist/frqtl/objects/instruments/hosted-eyes.js +268 -57
- package/dist/frqtl/objects/objects/QuantumEmitter.js +1 -1
- package/dist/frqtl/objects/record/Record.js +326 -0
- package/dist/frqtl/objects/record/open-record.js +22 -0
- package/dist/frqtl/objects/schema/index.js +72 -0
- package/dist/frqtl/parts/DetectorWall.js +1 -1
- package/dist/frqtl/parts/FrqtlControlsPanel.js +4 -2
- package/dist/frqtl/parts/FrqtlVision.js +21 -6
- package/dist/frqtl/parts/Wall.js +2 -0
- package/dist/frqtl/scenes/absorbing-wall-3d.js +18 -14
- package/dist/frqtl/scenes/absorbing-wall.js +18 -14
- package/dist/frqtl/scenes/atomic-model.js +3 -0
- package/dist/frqtl/scenes/big-bang.js +3 -0
- package/dist/frqtl/scenes/blackbody.js +14 -11
- package/dist/frqtl/scenes/circuit-sat.js +7 -4
- package/dist/frqtl/scenes/collision-matrix-3d.js +3 -0
- package/dist/frqtl/scenes/counting-wall-3d.js +19 -15
- package/dist/frqtl/scenes/counting-wall.js +19 -15
- package/dist/frqtl/scenes/double-slit.js +3 -0
- package/dist/frqtl/scenes/dse-one-emitter.js +64 -58
- package/dist/frqtl/scenes/dse-one-slit.js +59 -55
- package/dist/frqtl/scenes/dse-photoelectric.js +28 -24
- package/dist/frqtl/scenes/dse-tunnel-rebuild.js +124 -99
- package/dist/frqtl/scenes/dse-two-emitters.js +64 -58
- package/dist/frqtl/scenes/dse-two-slits.js +69 -65
- package/dist/frqtl/scenes/empty.js +3 -0
- package/dist/frqtl/scenes/laser-buildup.js +23 -16
- package/dist/frqtl/scenes/mirror-3d.js +31 -27
- package/dist/frqtl/scenes/mirror-route.js +4 -1
- package/dist/frqtl/scenes/mirror.js +24 -20
- package/dist/frqtl/scenes/omni-3d.js +7 -4
- package/dist/frqtl/scenes/omni-source.js +7 -4
- package/dist/frqtl/scenes/self-interference.js +13 -10
- package/dist/frqtl/scenes/smoking-gun.js +15 -11
- package/dist/frqtl/scenes/straight-walk.js +7 -4
- package/dist/frqtl/scenes/sun.js +11 -8
- package/dist/frqtl/scenes/two-source.js +22 -17
- package/dist/frqtl/scenes/wave.js +10 -7
- package/dist/shim/bundle/index.js +112 -96
- package/dist/shim/bundle/indexHtml.js +66 -39
- package/dist/shim/engine/router.js +2 -2
- package/dist/shim/index.js +1 -1
- package/dist/shim/notebook/format.js +1 -1
- package/dist/shim/notebook/store.js +2 -3
- package/dist/shim/page-params/index.js +2 -2
- package/dist/shim/project/index.js +20 -5
- package/dist/shim/project/link.js +182 -37
- package/dist/shim/project/manifest.js +151 -0
- package/dist/shim/project/parts-module.js +67 -0
- package/dist/shim/project/parts-writer.js +457 -0
- package/dist/shim/project/record-format.js +345 -0
- package/dist/shim/project/specifiers.js +41 -13
- package/dist/shim/registry/index.js +1 -1
- package/dist/shim/registry/scene-source.js +44 -30
- package/dist/shim/registry/walkthrough.js +13 -12
- package/dist/shim/render-state/apply.js +11 -14
- package/dist/shim/storage/codec-chains.js +88 -0
- package/dist/shim/storage/folders.js +205 -0
- package/dist/shim/storage/index.js +64 -8
- package/dist/shim/storage/make-namespace-store.js +5 -5
- package/llms.txt +2 -2
- package/package.json +1 -1
- package/dist/shim/bundle/frqnb.js +0 -112
- package/dist/shim/bundle/manifest.js +0 -95
- package/dist/shim/storage/modules.js +0 -249
- package/dist/shim/storage/projects.js +0 -150
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* A sketch file: the WHOLE scene as one ES module, `export default function buildExperiment(exp)`. The world
|
|
7
7
|
* (its co-init call, `exp.createCanvas` / `exp.createScene` — the one place its size is written),
|
|
8
|
-
* the parts (`exp.addObject`) and the render intent are all here; the sugar
|
|
8
|
+
* the parts (`export const parts` + `exp.declare`, or `exp.addObject`) and the render intent are all here; the sugar
|
|
9
9
|
* objects, renderer and engine are imports. Registered by lib/shim/registry/walkthrough.js
|
|
10
10
|
* (rung dse-two-slits).
|
|
11
11
|
*/
|
|
@@ -44,88 +44,92 @@
|
|
|
44
44
|
// fail-loud realisability check is repeated verbatim so a future λ edit here
|
|
45
45
|
// cannot silently drift from the pair it must match.
|
|
46
46
|
|
|
47
|
-
import { SphereEmitter } from '@descix/frqtl-web/parts';
|
|
47
|
+
import { SphereEmitter, Tunnel, Wall } from '@descix/frqtl-web/parts';
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
var detW = Math.round(lamPx / 64); // 5 — plate thickness (flux probe, sub-feature)
|
|
86
|
-
var sinkW = Math.round(lamPx / 16); // 20 — far-edge sink thickness
|
|
87
|
-
// ── THE LIGHT SOURCE — ONE emitter, behind the barrier, lighting BOTH slits ──
|
|
88
|
-
// preset 'hemisphere': 180 degrees of FORWARD emission, aimed at the barrier — the
|
|
89
|
-
// same walk-character (chargeMode/wavelength/fundamentalWaveLength) the slit exits must
|
|
90
|
-
// carry through so the exit's phase-locked point source is at the SAME λ_eff.
|
|
91
|
-
var SRC = {
|
|
49
|
+
// Two Slits — reproduces dse-two-emitters' picture with the two point sources built
|
|
50
|
+
// as SLIT EXITS in a barrier instead of two free emitters. Barrier = Wall segments
|
|
51
|
+
// (destroy); each slit = a directed Tunnel with the exit gate collapsed + phase-reset
|
|
52
|
+
// (the dse-tunnel-rebuild composition) so the mouth is a phase-locked point source.
|
|
53
|
+
const CW = 600, H = 400; // THE WORLD this scene states (its co-init call below)
|
|
54
|
+
// ── THE ONLY LENGTH — IDENTICAL to the canonical-leg pair ───────────────
|
|
55
|
+
const lamPx = 320;
|
|
56
|
+
const lamArg = 3.2; // fullness 1/3.2 = 0.3125 -> yellow
|
|
57
|
+
const fwl = 4 * (lamPx / lamArg); // 400 -> wavelengthScale floor(400/4) = 100
|
|
58
|
+
const wlScale = Math.floor(fwl / 4); // 100
|
|
59
|
+
// ── SLIT SEPARATION — IDENTICAL to dse-two-emitters' source separation ──
|
|
60
|
+
const legFrac = 1 / 4;
|
|
61
|
+
const D = Math.round(lamPx * legFrac); // 80 — the SAME leg, now measured from the
|
|
62
|
+
// slit EXIT plane, this apparatus's source plane
|
|
63
|
+
const sep = lamPx / 2; // 160 -> slit centres at y 120 and 280 — the
|
|
64
|
+
// EXACT y positions dse-two-emitters used
|
|
65
|
+
const cy = Math.round(H / 2); // 200
|
|
66
|
+
const slitCY1 = cy - sep / 2, slitCY2 = cy + sep / 2; // 120, 280
|
|
67
|
+
// ── THE BARRIER — one opaque plate, two slit apertures ──────────────────
|
|
68
|
+
const barrierW = Math.round(lamPx / 8); // 40 — plate thickness (dimensionless x lamPx,
|
|
69
|
+
// an independent dial from the transverse
|
|
70
|
+
// wavelength, same discipline as dse-tunnel-rebuild)
|
|
71
|
+
const slitH = Math.round(lamPx / 8); // 40 — slit aperture height (before liners)
|
|
72
|
+
const linerH = Math.round(lamPx / 64); // 5 — liner thickness (unjumpable: max step 2px/tick)
|
|
73
|
+
const bore = slitH - 2 * linerH; // 30 — the clear aperture between the liners
|
|
74
|
+
const srcX = Math.round(lamPx / 16); // 20 — the emitter, well behind the barrier
|
|
75
|
+
const barrierL = srcX + Math.round(lamPx / 2); // 180 — half a wavelength of travel room
|
|
76
|
+
const slit1Top = slitCY1 - slitH / 2, slit2Top = slitCY2 - slitH / 2; // 100, 260
|
|
77
|
+
const exitX = barrierL + barrierW; // 220 — the slit EXIT plane (barrier back face)
|
|
78
|
+
const detX = exitX + D; // 300 — SAME leg as dse-two-emitters, now
|
|
79
|
+
// measured from the slit exits
|
|
80
|
+
const detW = Math.round(lamPx / 64); // 5 — plate thickness (flux probe, sub-feature)
|
|
81
|
+
const sinkW = Math.round(lamPx / 16); // 20 — far-edge sink thickness
|
|
82
|
+
|
|
83
|
+
export const parts = {
|
|
84
|
+
source: [SphereEmitter, {
|
|
92
85
|
preset: 'hemisphere', is2D: true, chargeMode: 'random', center: [srcX, cy],
|
|
93
86
|
wavelength: lamArg, fundamentalDimension: 2, fundamentalWaveLength: fwl,
|
|
94
87
|
burstSize: 8, emitEveryTicks: 1
|
|
95
|
-
}
|
|
96
|
-
exp.createCanvas(CW, H, SphereEmitter.worldCfg(SRC)); // THE WORLD: a 2D canvas + universe — first, then parts
|
|
97
|
-
exp.addObject('SphereEmitter', SRC);
|
|
88
|
+
}],
|
|
98
89
|
// Barrier segments — opaque destroy sinks, leaving the two slit gaps.
|
|
99
|
-
|
|
100
|
-
collisionBehavior: 'destroy',
|
|
101
|
-
|
|
102
|
-
collisionBehavior: 'destroy',
|
|
103
|
-
|
|
104
|
-
collisionBehavior: 'destroy',
|
|
90
|
+
wall1: [Wall, { rect: [barrierL, 0, barrierW, slit1Top],
|
|
91
|
+
collisionBehavior: 'destroy', color: [200, 60, 60] }],
|
|
92
|
+
wall2: [Wall, { rect: [barrierL, slit1Top + slitH, barrierW, slit2Top - (slit1Top + slitH)],
|
|
93
|
+
collisionBehavior: 'destroy', color: [150, 40, 40] }],
|
|
94
|
+
wall3: [Wall, { rect: [barrierL, slit2Top + slitH, barrierW, H - (slit2Top + slitH)],
|
|
95
|
+
collisionBehavior: 'destroy', color: [200, 60, 60] }],
|
|
105
96
|
// The two slit channels — directed Tunnels, exit gate COLLAPSED + PHASE-RESET (the
|
|
106
97
|
// dse-tunnel-rebuild composition): each channel's own mouth stands in for a point
|
|
107
98
|
// source at the slit's own y, phase-locked — what a SphereEmitter would do at that pixel.
|
|
108
|
-
|
|
99
|
+
slit1_channel: [Tunnel, {
|
|
109
100
|
left: barrierL, top: slit1Top + linerH, length: barrierW, bore: bore,
|
|
110
101
|
wallThickness: linerH, axis: 'x', mode: 'directed',
|
|
111
102
|
exitCollapse: true, exitRecenter: true, exitPhaseReset: true,
|
|
112
|
-
|
|
113
|
-
}
|
|
114
|
-
|
|
103
|
+
color: [80, 140, 220]
|
|
104
|
+
}],
|
|
105
|
+
slit2_channel: [Tunnel, {
|
|
115
106
|
left: barrierL, top: slit2Top + linerH, length: barrierW, bore: bore,
|
|
116
107
|
wallThickness: linerH, axis: 'x', mode: 'directed',
|
|
117
108
|
exitCollapse: true, exitRecenter: true, exitPhaseReset: true,
|
|
118
|
-
|
|
119
|
-
}
|
|
109
|
+
color: [80, 140, 220]
|
|
110
|
+
}],
|
|
120
111
|
// FAR-EDGE SINK — the same experiment-boundary sink the canonical-leg pair uses.
|
|
121
|
-
|
|
122
|
-
|
|
112
|
+
far_sink: [Wall, { rect: [CW - sinkW, 0, sinkW, H], collisionBehavior: 'destroy',
|
|
113
|
+
color: [120, 120, 120], alpha: 40 }],
|
|
123
114
|
// ── THE PLATE — SAME instrument as the canonical-leg pair: a counting wall that does
|
|
124
115
|
// NOT absorb, at the SAME leg D past the new source plane (the slit exits).
|
|
125
|
-
|
|
126
|
-
preset: 'transparent-probe', markTag: 'plate',
|
|
116
|
+
screen: [Wall, { rect: [detX, 0, detW, H],
|
|
117
|
+
preset: 'transparent-probe', markTag: 'plate', color: [120, 200, 120] }],
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
export default function buildExperiment(exp) {
|
|
121
|
+
if (Math.abs(lamArg * wlScale - lamPx) > 1e-9) {
|
|
122
|
+
throw new Error('[dse-two-slits] lamPx ' + lamPx + ' is not realisable as lambda_eff: the ' +
|
|
123
|
+
'engine can only produce wavelengthArg x floor(fwl/4) = ' + (lamArg * wlScale) + '. (FAIL-LOUD.)');
|
|
124
|
+
}
|
|
125
|
+
// ── THE LIGHT SOURCE — ONE emitter, behind the barrier, lighting BOTH slits ──
|
|
126
|
+
// preset 'hemisphere': 180 degrees of FORWARD emission, aimed at the barrier — the
|
|
127
|
+
// same walk-character (chargeMode/wavelength/fundamentalWaveLength) the slit exits must
|
|
128
|
+
// carry through so the exit's phase-locked point source is at the SAME λ_eff.
|
|
129
|
+
exp.createCanvas(CW, H, SphereEmitter.worldCfg(parts.source[1])); // THE WORLD: a 2D canvas + universe — first, then parts
|
|
130
|
+
const p = exp.declare(parts);
|
|
127
131
|
exp.addObject('LiveChart', {
|
|
128
|
-
source: screen, orientation: 90,
|
|
132
|
+
source: p.screen, orientation: 90,
|
|
129
133
|
rect: [detX + detW + 8, 0, Math.max(60, CW - (detX + detW + 8) - 8), H],
|
|
130
134
|
series: 'line', label: 'count by y', refreshMs: 100, color: [24, 32, 46], alpha: 225
|
|
131
135
|
});
|
|
@@ -8,7 +8,10 @@
|
|
|
8
8
|
* lib/shim/registry/scene-source.js::EMPTY_SCENE (not a walk-through rung).
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
+
export const parts = {};
|
|
12
|
+
|
|
11
13
|
export default function buildExperiment(exp) {
|
|
12
14
|
// THE WORLD: a 600x400 2D canvas + universe on the dim-2 fundamental, λ multiplier 8.
|
|
13
15
|
exp.createCanvas(600, 400, { dimension: 2, wavelengthScale: 8 });
|
|
16
|
+
exp.declare(parts);
|
|
14
17
|
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* A sketch file: the WHOLE scene as one ES module, `export default function buildExperiment(exp)`. The world
|
|
7
7
|
* (its co-init call, `exp.createCanvas` / `exp.createScene` — the one place its size is written),
|
|
8
|
-
* the parts (`exp.addObject`) and the render intent are all here; the sugar
|
|
8
|
+
* the parts (`export const parts` + `exp.declare`, or `exp.addObject`) and the render intent are all here; the sugar
|
|
9
9
|
* objects, renderer and engine are imports. Registered by lib/shim/registry/walkthrough.js
|
|
10
10
|
* (rung r4b-laser-buildup).
|
|
11
11
|
*/
|
|
@@ -26,24 +26,31 @@
|
|
|
26
26
|
|
|
27
27
|
import { SphereEmitter, Tunnel } from '@descix/frqtl-web/parts';
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
29
|
+
// Laser Build-Up — gain source + resonant bore + output coupler.
|
|
30
|
+
// Geometry and per-leaf creation conditions come from the ONE scene-spec authority,
|
|
31
|
+
// Tunnel.pointExitSpec() (setupTunnelPointExit.sceneSpec), so this rung and the standalone page cannot drift.
|
|
32
|
+
const W = 600, H = 400; // THE WORLD this scene states (its co-init call below)
|
|
33
|
+
const SPEC = Tunnel.pointExitSpec({
|
|
34
|
+
canvasW: W, canvasH: H,
|
|
35
|
+
tunnelLength: 240, // REBUILD-class: corridor geometry, re-authored not dragged
|
|
36
|
+
wavelengthScale: 16, // eff lambda 256px — the self-interference golden's own regime
|
|
37
|
+
exitRecenter: true, // output coupler collapses the mouth to a point
|
|
38
|
+
exitPhaseReset: false // coherence OFF by default — turning it ON is the experiment
|
|
39
|
+
});
|
|
40
|
+
// The spec names its tunnel; in `parts` the key is the name.
|
|
41
|
+
const { name: _tunnelName, ...TUNNEL } = SPEC.tunnel;
|
|
42
|
+
|
|
43
|
+
export const parts = {
|
|
41
44
|
// 1. THE GAIN SOURCE — a hemisphere emitter just inside the input mouth, so the whole
|
|
42
45
|
// burst is aimed down the bore instead of half of it escaping backwards.
|
|
43
|
-
|
|
44
|
-
exp.addObject('SphereEmitter', spec.emitter);
|
|
46
|
+
emitter: [SphereEmitter, { ...SPEC.emitter }],
|
|
45
47
|
// 2+3. THE BORE AND THE OUTPUT COUPLER — one directed Tunnel carrying the exit gate.
|
|
46
48
|
// mode 'directed': every wall hit re-emits forward within 180 degrees of the axis.
|
|
47
49
|
// exitRecenter / exitPhaseReset are the two coupler flags, both live in the Inspector.
|
|
48
|
-
|
|
50
|
+
point_exit_tunnel: [Tunnel, { ...TUNNEL }],
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export default function buildExperiment(exp) {
|
|
54
|
+
exp.createCanvas(W, H, SphereEmitter.worldCfg(parts.emitter[1])); // THE WORLD: a 2D canvas + universe — first, then parts
|
|
55
|
+
exp.declare(parts);
|
|
49
56
|
}
|
|
@@ -5,40 +5,39 @@
|
|
|
5
5
|
*
|
|
6
6
|
* A sketch file: the WHOLE scene as one ES module, `export default function buildExperiment(exp)`. The world
|
|
7
7
|
* (its co-init call, `exp.createCanvas` / `exp.createScene` — the one place its size is written),
|
|
8
|
-
* the parts (`exp.addObject`) and the render intent are all here; the sugar
|
|
8
|
+
* the parts (`export const parts` + `exp.declare`, or `exp.addObject`) and the render intent are all here; the sugar
|
|
9
9
|
* objects, renderer and engine are imports. Registered by lib/shim/registry/walkthrough.js
|
|
10
10
|
* (rung cl1a-mirror-3d).
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import { SphereEmitter } from '@descix/frqtl-web/parts';
|
|
13
|
+
import { SphereEmitter, Wall } from '@descix/frqtl-web/parts';
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
15
|
+
// Collision Lab 1A · 3D — a collimated LASER (particle-walk pins PURE +x in 2D AND
|
|
16
|
+
// 3D) into a 3D mirror SLAB (depth → z-slab containing z=0), rendered as a box;
|
|
17
|
+
// orbit to view. Same LASER tuning as the 2D 1A: single positive
|
|
18
|
+
// charge, wavelength 1, wavelengthScale 1 (fundamentalWaveLength 4), tiny burst.
|
|
19
|
+
// FACE-ON default: orientation 0 presents the full
|
|
20
|
+
// drawn face to the beam → retro-reflection (beam straight back, recolored) — the
|
|
21
|
+
// one mirror visual that reads correctly from EVERY camera azimuth. (A tilted
|
|
22
|
+
// default's L-shaped 2th exit is correct optics but its mirror-flipped projection
|
|
23
|
+
// reads as pass-through from presets that view the xy-plane from behind — measured:
|
|
24
|
+
// zero leaves ever behind the face; the read was projection handedness, not physics.)
|
|
25
|
+
// Rotate the orientation slider to steer: 45 -> straight up, 30 -> R(120), etc.
|
|
26
|
+
const W = 600, H = 400; // THE WORLD this scene states (its co-init call below)
|
|
27
|
+
const cy = Math.round(H / 2);
|
|
28
|
+
|
|
29
|
+
export const parts = {
|
|
30
|
+
source: [SphereEmitter, {
|
|
30
31
|
preset: 'particle-walk', is2D: false, center: [Math.round(W * 0.15), cy],
|
|
31
32
|
chargeMode: 'positive', fundamentalDimension: 2, wavelength: 1,
|
|
32
33
|
fundamentalWaveLength: 4, burstSize: 2, emitEveryTicks: 1
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
exp.addObject('SphereEmitter', SRC);
|
|
36
|
-
exp.addObject('Wall', {
|
|
34
|
+
}],
|
|
35
|
+
mirror: [Wall, {
|
|
37
36
|
rect: [Math.round(W * 0.6), Math.round(H * 0.2), 20, Math.round(H * 0.6)],
|
|
38
37
|
z: -80, depth: 160,
|
|
39
38
|
collisionBehavior: 'bounce', bounceDirection: 'reflect', orientationDeg: 0,
|
|
40
|
-
|
|
41
|
-
}
|
|
39
|
+
color: [255, 120, 0], hooks: ['recolor']
|
|
40
|
+
}],
|
|
42
41
|
// SCENE Z-COLLIMATOR (without it the z lets things pass through instead of
|
|
43
42
|
// reflecting): the beam's z-tail DIFFUSES over time (measured:
|
|
44
43
|
// |z| at the wall trending 68 of the 80 rim within seconds), and any quantum
|
|
@@ -49,8 +48,13 @@ export default function buildExperiment(exp) {
|
|
|
49
48
|
// dying at the canvas edge) — so the mirror provably faces EVERY alive quantum
|
|
50
49
|
// and nothing can ever appear past the plate. 40px deep: un-jumpable (max z
|
|
51
50
|
// step is ±2/tick).
|
|
52
|
-
|
|
53
|
-
collisionBehavior: 'destroy',
|
|
54
|
-
|
|
55
|
-
collisionBehavior: 'destroy',
|
|
51
|
+
zClipFar: [Wall, { rect: [0, 0, W, H], z: 80, depth: 40,
|
|
52
|
+
collisionBehavior: 'destroy', visible: false }],
|
|
53
|
+
zClipNear: [Wall, { rect: [0, 0, W, H], z: -120, depth: 40,
|
|
54
|
+
collisionBehavior: 'destroy', visible: false }],
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export default function buildExperiment(exp) {
|
|
58
|
+
exp.createScene(W, H, 600, SphereEmitter.worldCfg(parts.source[1])); // THE WORLD: a 3D scene + universe, 600x400x600 — first, then parts
|
|
59
|
+
exp.declare(parts);
|
|
56
60
|
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* A sketch file: the WHOLE scene as one ES module, `export default function buildExperiment(exp)`. The world
|
|
7
7
|
* (its co-init call, `exp.createCanvas` / `exp.createScene` — the one place its size is written),
|
|
8
|
-
* the parts (`exp.addObject`) and the render intent are all here; the sugar
|
|
8
|
+
* the parts (`export const parts` + `exp.declare`, or `exp.addObject`) and the render intent are all here; the sugar
|
|
9
9
|
* objects, renderer and engine are imports. Registered by lib/shim/registry/walkthrough.js
|
|
10
10
|
* (rung cl1d-mirror-route).
|
|
11
11
|
*/
|
|
@@ -37,6 +37,8 @@
|
|
|
37
37
|
import { CameraControls, SphereEmitter } from '@descix/frqtl-web/parts';
|
|
38
38
|
import * as FrqtlDisplay from '@descix/frqtl-web/compat/renderer/display-slot.js';
|
|
39
39
|
|
|
40
|
+
export const parts = {};
|
|
41
|
+
|
|
40
42
|
export default function buildExperiment(exp) {
|
|
41
43
|
// The booted display (the host's renderState.renderer) decides which world this mode makes.
|
|
42
44
|
var IS3D = FrqtlDisplay.name() === 'three';
|
|
@@ -101,6 +103,7 @@ export default function buildExperiment(exp) {
|
|
|
101
103
|
// THE WORLD — first, then parts: a 3D scene + universe (600x400x600) or a 2D canvas + universe.
|
|
102
104
|
if (IS3D) { exp.createScene(W, H, WORLD_D, SphereEmitter.worldCfg(SRC)); }
|
|
103
105
|
else { exp.createCanvas(W, H, SphereEmitter.worldCfg(SRC)); }
|
|
106
|
+
exp.declare(parts);
|
|
104
107
|
exp.addObject('SphereEmitter', SRC);
|
|
105
108
|
// The ten mirrors at the star vertices — each its own colour + the recolor tag. In 3D each is a
|
|
106
109
|
// SLAB (z-slab −SD/2..SD/2); in 2D the bag is EMPTY, so the wall is the flat mirror.
|
|
@@ -5,34 +5,38 @@
|
|
|
5
5
|
*
|
|
6
6
|
* A sketch file: the WHOLE scene as one ES module, `export default function buildExperiment(exp)`. The world
|
|
7
7
|
* (its co-init call, `exp.createCanvas` / `exp.createScene` — the one place its size is written),
|
|
8
|
-
* the parts (`exp.addObject`) and the render intent are all here; the sugar
|
|
8
|
+
* the parts (`export const parts` + `exp.declare`, or `exp.addObject`) and the render intent are all here; the sugar
|
|
9
9
|
* objects, renderer and engine are imports. Registered by lib/shim/registry/walkthrough.js
|
|
10
10
|
* (rung cl1a-mirror).
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import { SphereEmitter } from '@descix/frqtl-web/parts';
|
|
13
|
+
import { SphereEmitter, Wall } from '@descix/frqtl-web/parts';
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
15
|
+
// Collision Lab 1A (Mirror) — a collimated LASER aimed at a rotatable Bounce/Reflect
|
|
16
|
+
// Wall. LASER TUNING: particle-walk pins PURE +x momentum (the
|
|
17
|
+
// tightest constrained-angle the emitter supports — zero angular spread); a SINGLE
|
|
18
|
+
// (positive) charge removes the random transverse braiding; wavelength 1 → the
|
|
19
|
+
// minimal transverse wiggle; fundamentalWaveLength 4 → wavelengthScale 1 (the
|
|
20
|
+
// 256px scale-spread REMOVED — that spray was the 'visually non-sensical' look);
|
|
21
|
+
// a TINY burst (2/tick) keeps it a thin beam (frame-rate protection). Rotate the
|
|
22
|
+
// mirror to steer the reflected beam: 45 -> straight-up exit, 30 -> R(120) exit.
|
|
23
|
+
const W = 600, H = 400; // THE WORLD this scene states (its co-init call below)
|
|
24
|
+
const cy = Math.round(H / 2);
|
|
25
|
+
|
|
26
|
+
export const parts = {
|
|
27
|
+
source: [SphereEmitter, {
|
|
27
28
|
preset: 'particle-walk', is2D: true, center: [Math.round(W * 0.12), cy],
|
|
28
29
|
orientationDeg: 0, chargeMode: 'positive', fundamentalDimension: 2, wavelength: 1,
|
|
29
30
|
fundamentalWaveLength: 4, burstSize: 2, emitEveryTicks: 1
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
exp.addObject('SphereEmitter', SRC);
|
|
33
|
-
exp.addObject('Wall', {
|
|
31
|
+
}],
|
|
32
|
+
mirror: [Wall, {
|
|
34
33
|
rect: [Math.round(W * 0.6), Math.round(H * 0.2), 20, Math.round(H * 0.6)],
|
|
35
34
|
collisionBehavior: 'bounce', bounceDirection: 'reflect',
|
|
36
|
-
orientationDeg: 45,
|
|
37
|
-
}
|
|
35
|
+
orientationDeg: 45, color: [255, 120, 0], hooks: ['recolor']
|
|
36
|
+
}],
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export default function buildExperiment(exp) {
|
|
40
|
+
exp.createCanvas(W, H, SphereEmitter.worldCfg(parts.source[1])); // THE WORLD: a 2D canvas + universe — first, then parts
|
|
41
|
+
exp.declare(parts);
|
|
38
42
|
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* A sketch file: the WHOLE scene as one ES module, `export default function buildExperiment(exp)`. The world
|
|
7
7
|
* (its co-init call, `exp.createCanvas` / `exp.createScene` — the one place its size is written),
|
|
8
|
-
* the parts (`exp.addObject`) and the render intent are all here; the sugar
|
|
8
|
+
* the parts (`export const parts` + `exp.declare`, or `exp.addObject`) and the render intent are all here; the sugar
|
|
9
9
|
* objects, renderer and engine are imports. Registered by lib/shim/registry/walkthrough.js
|
|
10
10
|
* (rung r7-3d).
|
|
11
11
|
*/
|
|
@@ -14,13 +14,16 @@
|
|
|
14
14
|
|
|
15
15
|
import { CameraControls, SphereEmitter } from '@descix/frqtl-web/parts';
|
|
16
16
|
|
|
17
|
+
export const parts = {
|
|
18
|
+
source: [SphereEmitter, { preset: 'spherical', is2D: false }],
|
|
19
|
+
};
|
|
20
|
+
|
|
17
21
|
export default function buildExperiment(exp) {
|
|
18
22
|
// is2D:false opens the z-axis: the ball-rejected sampler draws a 3D BALL of
|
|
19
23
|
// directions (bench S1). three renderer + perspective camera come from renderState.
|
|
20
24
|
// CameraControls.attach = reusable FAIL-SOFT joystick sugar (no-op in 2D).
|
|
21
|
-
|
|
22
|
-
exp.
|
|
23
|
-
exp.addObject('SphereEmitter', SRC);
|
|
25
|
+
exp.createScene(600, 400, 600, SphereEmitter.worldCfg(parts.source[1])); // THE WORLD: a 3D scene + universe, 600x400x600 — first, then parts
|
|
26
|
+
exp.declare(parts);
|
|
24
27
|
if (typeof document !== 'undefined' && exp.runner) {
|
|
25
28
|
if (exp.runner.controlHost) { CameraControls.attach(exp.runner, exp.runner.controlHost); }
|
|
26
29
|
}
|
|
@@ -5,18 +5,21 @@
|
|
|
5
5
|
*
|
|
6
6
|
* A sketch file: the WHOLE scene as one ES module, `export default function buildExperiment(exp)`. The world
|
|
7
7
|
* (its co-init call, `exp.createCanvas` / `exp.createScene` — the one place its size is written),
|
|
8
|
-
* the parts (`exp.addObject`) and the render intent are all here; the sugar
|
|
8
|
+
* the parts (`export const parts` + `exp.declare`, or `exp.addObject`) and the render intent are all here; the sugar
|
|
9
9
|
* objects, renderer and engine are imports. Registered by lib/shim/registry/walkthrough.js
|
|
10
10
|
* (rung r3-omni-source).
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import { SphereEmitter } from '@descix/frqtl-web/parts';
|
|
14
14
|
|
|
15
|
+
export const parts = {
|
|
16
|
+
source: [SphereEmitter, { preset: 'spherical', is2D: true }],
|
|
17
|
+
};
|
|
18
|
+
|
|
15
19
|
export default function buildExperiment(exp) {
|
|
16
20
|
// Rung 3 — full dispersion: the spherical preset draws (vx,vy) across the whole
|
|
17
21
|
// ball; in 2D the ball-rejected sampler collapses to an even DISK of directions
|
|
18
22
|
// (bench S5). One omni point source = the sun disk.
|
|
19
|
-
|
|
20
|
-
exp.
|
|
21
|
-
exp.addObject('SphereEmitter', SRC);
|
|
23
|
+
exp.createCanvas(600, 400, SphereEmitter.worldCfg(parts.source[1])); // THE WORLD: a 2D canvas + universe — first, then parts
|
|
24
|
+
exp.declare(parts);
|
|
22
25
|
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* A sketch file: the WHOLE scene as one ES module, `export default function buildExperiment(exp)`. The world
|
|
7
7
|
* (its co-init call, `exp.createCanvas` / `exp.createScene` — the one place its size is written),
|
|
8
|
-
* the parts (`exp.addObject`) and the render intent are all here; the sugar
|
|
8
|
+
* the parts (`export const parts` + `exp.declare`, or `exp.addObject`) and the render intent are all here; the sugar
|
|
9
9
|
* objects, renderer and engine are imports. Registered by lib/shim/registry/walkthrough.js
|
|
10
10
|
* (rungs r4-self-interference, r5-fountain-pool).
|
|
11
11
|
*/
|
|
@@ -19,6 +19,16 @@
|
|
|
19
19
|
|
|
20
20
|
import { SphereEmitter } from '@descix/frqtl-web/parts';
|
|
21
21
|
|
|
22
|
+
export const parts = {
|
|
23
|
+
source: [SphereEmitter, {
|
|
24
|
+
is2D: true, preset: 'spherical',
|
|
25
|
+
emissionShell: 'surface', innerR: 16,
|
|
26
|
+
fundamentalDimension: 2, wavelength: 32,
|
|
27
|
+
chargeMode: 'random', fundamentalWaveLength: 64,
|
|
28
|
+
burstSize: 72, emitEveryTicks: 1
|
|
29
|
+
}],
|
|
30
|
+
};
|
|
31
|
+
|
|
22
32
|
export default function buildExperiment(exp) {
|
|
23
33
|
// The classic self-interference tuple (matches self-interference-preset.png):
|
|
24
34
|
// dim 2 (capacity 16) + wavelength 32 -> clamped to 16 -> mass 1 (fullness 1/16);
|
|
@@ -27,13 +37,6 @@ export default function buildExperiment(exp) {
|
|
|
27
37
|
// emissionShell 'surface' + innerR 16 -> RING launch (empty center, sharp bands);
|
|
28
38
|
// burst 72/tick. Red is DERIVED from fullness 1/16 (ROYGBIV low end), not forced.
|
|
29
39
|
// Pattern = radial BRAIDED BANDS (not concentric rings).
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
emissionShell: 'surface', innerR: 16,
|
|
33
|
-
fundamentalDimension: 2, wavelength: 32,
|
|
34
|
-
chargeMode: 'random', fundamentalWaveLength: 64,
|
|
35
|
-
burstSize: 72, emitEveryTicks: 1
|
|
36
|
-
};
|
|
37
|
-
exp.createCanvas(600, 400, SphereEmitter.worldCfg(SRC)); // THE WORLD: a 2D canvas + universe — first, then parts
|
|
38
|
-
exp.addObject('SphereEmitter', SRC);
|
|
40
|
+
exp.createCanvas(600, 400, SphereEmitter.worldCfg(parts.source[1])); // THE WORLD: a 2D canvas + universe — first, then parts
|
|
41
|
+
exp.declare(parts);
|
|
39
42
|
}
|
|
@@ -56,24 +56,27 @@
|
|
|
56
56
|
|
|
57
57
|
import { CameraControls, CollisionTypes, LargeObject, SphereEmitter } from '@descix/frqtl-web/parts';
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
var RAMP_START = 180, RAMP_END = 600; // the wind-down: full burst until RAMP_START, zero at RAMP_END
|
|
64
|
-
var GUN_W = 150, GUN_H = 84; // the painted gun body (px); its right edge is the muzzle
|
|
59
|
+
const W = 600, H = 600, D = 600; // THE WORLD this scene states (its co-init call below)
|
|
60
|
+
const BURST = 20; // quanta per tick at the muzzle, before the wind-down
|
|
61
|
+
const BULLET_SIDE = 10; // the bullet cube's edge = the muzzle slit's height (px)
|
|
62
|
+
const MUZZLE_X = Math.floor(W / 2), MUZZLE_Y = Math.floor(H / 2);
|
|
65
63
|
|
|
66
|
-
|
|
67
|
-
|
|
64
|
+
export const parts = {
|
|
65
|
+
muzzle: [SphereEmitter, {
|
|
68
66
|
preset: 'particle-walk', is2D: false, // pure +X momentum in 2D and 3D
|
|
69
67
|
center: [MUZZLE_X, MUZZLE_Y, 0],
|
|
70
68
|
emissionBox: { x: 0, y: BULLET_SIDE, z: 0 }, // the 1×10 slit
|
|
71
69
|
chargeMode: 'negative', burstSize: BURST, emitEveryTicks: 1,
|
|
72
70
|
fundamentalDimension: 0, fundamentalWaveLength: 64 // λ scale floor(64/4) = 16
|
|
73
|
-
}
|
|
71
|
+
}],
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export default function buildExperiment(exp) {
|
|
75
|
+
var RAMP_START = 180, RAMP_END = 600; // the wind-down: full burst until RAMP_START, zero at RAMP_END
|
|
76
|
+
var GUN_W = 150, GUN_H = 84; // the painted gun body (px); its right edge is the muzzle
|
|
74
77
|
|
|
75
78
|
// ── WORLD — a 3D scene + universe W×H×D, fundamental layer 0, λ multiplier 16 ──
|
|
76
|
-
exp.createScene(W, H, D, SphereEmitter.worldCfg(
|
|
79
|
+
exp.createScene(W, H, D, SphereEmitter.worldCfg(parts.muzzle[1]));
|
|
77
80
|
var u = exp.universe;
|
|
78
81
|
u.brownianMotion = true;
|
|
79
82
|
u.withInterQuantumCollisions = true;
|
|
@@ -83,7 +86,8 @@ export default function buildExperiment(exp) {
|
|
|
83
86
|
exp.runner.setRateLimits({ tpsLimit: 60 }); // pacing only: 60 ticks = 1 s of wall-clock
|
|
84
87
|
|
|
85
88
|
// ── THE MUZZLE ──
|
|
86
|
-
|
|
89
|
+
const p = exp.declare(parts);
|
|
90
|
+
var muzzle = p.muzzle;
|
|
87
91
|
|
|
88
92
|
// ── THE WIND-DOWN — the burst falls linearly from BURST at RAMP_START to zero at RAMP_END ──
|
|
89
93
|
// The burst setter's floor is one quantum per tick, so zero is the muzzle's cut, issued once.
|
|
@@ -5,18 +5,21 @@
|
|
|
5
5
|
*
|
|
6
6
|
* A sketch file: the WHOLE scene as one ES module, `export default function buildExperiment(exp)`. The world
|
|
7
7
|
* (its co-init call, `exp.createCanvas` / `exp.createScene` — the one place its size is written),
|
|
8
|
-
* the parts (`exp.addObject`) and the render intent are all here; the sugar
|
|
8
|
+
* the parts (`export const parts` + `exp.declare`, or `exp.addObject`) and the render intent are all here; the sugar
|
|
9
9
|
* objects, renderer and engine are imports. Registered by lib/shim/registry/walkthrough.js
|
|
10
10
|
* (rung r1-straight-walk).
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import { SphereEmitter } from '@descix/frqtl-web/parts';
|
|
14
14
|
|
|
15
|
+
export const parts = {
|
|
16
|
+
source: [SphereEmitter, { preset: 'particle-walk', is2D: true }],
|
|
17
|
+
};
|
|
18
|
+
|
|
15
19
|
export default function buildExperiment(exp) {
|
|
16
20
|
// Rung 1 — deterministic +X drift (particle-walk preset pins vx=[R,R], vy=vz=0)
|
|
17
21
|
// with the tiny always-armed transverse coin. Born AT the fundamental (dim 0)
|
|
18
22
|
// so it is 'light' — steps every tick (fast straight drift).
|
|
19
|
-
|
|
20
|
-
exp.
|
|
21
|
-
exp.addObject('SphereEmitter', SRC);
|
|
23
|
+
exp.createCanvas(600, 400, SphereEmitter.worldCfg(parts.source[1])); // THE WORLD: a 2D canvas + universe — first, then parts
|
|
24
|
+
exp.declare(parts);
|
|
22
25
|
}
|