/ proof-of-concept / toy-instruments
Sign in
proof-of-concept / toy-instruments
toy-instruments / src / sim / types.ts
101 lines · 4.3 KBCodeBlameHistory
4a8abcfString of beads: 3D bead-spring solver, control panel, waveform, spectrogram, wav, displacement viewerJeremy Magland 1// Generic bead-spring system in 3D. Instruments build one of these; the solver
2// integrates it. SI units throughout.
4export interface Anchor {
5 pos: [number, number, number];
6 // -1: fixed point. Otherwise a massless ring on a rod: x fixed, y and z
7 // follow this bead, so the spring to it stays parallel to x (no transverse force).
8 slideBead: number;
9}
11export interface BeadSystem {
12 n: number; // number of beads
13 rest: Float64Array; // 3n equilibrium positions
14 mass: Float64Array; // n
15 pinned: Uint8Array; // n, 1 = held fixed at rest position
16 anchors: Anchor[]; // node index n + a
17 // springs: endpoints are node indices (bead < n, anchor >= n)
18 si: Int32Array;
19 sj: Int32Array;
20 sk: Float64Array; // stiffness (N/m)
21 sL0: Float64Array; // rest length (m)
22 sc: Float64Array; // dashpot on relative velocity, all 3 components (N s/m)
23 sigma0: number; // mass-proportional damping: force -2 sigma0 m v
591834dCymbal: free plate with rigid-body motion removed (no support); lighter default dampingJeremy Magland 24 // remove rigid-body motion (translation and rotation, mass-weighted) from the
25 // beads' accelerations and velocities: a free body whose rigid modes are not
26 // simulated. The elastic modes are unchanged (they are mass-orthogonal to them).
27 freeRigid?: boolean;
31// Plate bending (Poisson ratio built into M). Hinge e measures the dihedral
32// angle across edge (e0, e1) shared by triangles (e0, e1, w0) and (e1, e0, w1);
33// phi_e = sign_e (theta_e - theta0_e) is its change, positive when the surface
34// folds toward its upward normal. Triangle t holds up to three hinges
35// (-1 = free edge) and has energy 1/2 phi^T M phi; M is the plate energy
36// A D/2 [(tr S)^2 - 2 (1 - nu) det S] of the shape operator
37// S = sum_e phi_e l_e / (2A) m_e m_e^T, condensed over free edges (no moment there).
38// Damping: the moments use phi + 2 sigma1 dphi/dt (Rayleigh, sigma1 omega^2).
39export interface Bending {
40 w0: Int32Array;
41 w1: Int32Array;
42 e0: Int32Array;
43 e1: Int32Array;
44 sign: Float64Array;
45 theta0: Float64Array;
46 tri: Int32Array; // 3 per triangle
47 M: Float64Array; // 9 per triangle
48 sigma1: number;
51export interface Excitation {
52 u0: Float64Array; // 3n initial displacement from rest
53 v0: Float64Array; // 3n initial velocity
54 // External force F(t) = shape * F0 * 0.5 (1 - cos(2 pi t / tau)), 0 <= t <= tau
55 force?: { shape: Float64Array; F0: number; tau: number };
57 // Normal force K delta^p with delta = (q - sum_i w_i (x_i - rest_i)) . normal;
58 // Coulomb friction mu * normal force against tangential slip.
59 // Starts at q = 0 (just touching the undeformed patch) with velocity vel0.
63export interface Mallet {
64 weights: Float64Array; // n, sums to 1 (contact patch)
66 vel0: [number, number, number]; // m/s; its component along normal must be > 0
68 K: number; // N / m^p
69 p: number;
71 // no contact once the mallet has slid this far sideways from the patch (m); default unlimited
72 reach?: number;
75export interface SimOptions {
76 duration: number; // s
77 fs: number; // audio sample rate (Hz)
78 cfl: number; // fraction of the leapfrog stability limit 2/omega_max
79 frameRate: number; // displacement frames per second
80 pickup: Float64Array; // 3n weights; audio = sum w . acceleration
c696b9aCymbal: plate bending via per-triangle shape operators, felt centre support, stick and mallet with angle and friction, far-field microphoneJeremy Magland 81 // optional per-bead delay in samples (a microphone): bead i's term arrives delay[i] later
82 pickupDelay?: Float64Array;
85export interface SimResult {
86 audio: Float32Array; // pickup acceleration (m/s^2) at fs
87 fs: number;
88 frames: Float32Array; // nFrames x 3n displacement from rest
89 frameTimes: Float64Array;
90 energy: Float64Array; // mechanical energy above equilibrium at frame times (J)
91 balance: Float64Array; // E + dissipated - work_in - E0 at frame times (J)
92 dt: number;
93 stepsPerSample: number;
94 omegaMax: number;
95 wallSeconds: number;
c696b9aCymbal: plate bending via per-triangle shape operators, felt centre support, stick and mallet with angle and friction, far-field microphoneJeremy Magland 96 maxStretch: number; // largest |l - L0| / L0 of bead-to-bead springs, at frame times
2cd36faBead drum: hex-lattice round head, felt mallet contact, top view and cross-section; shared instrument pageJeremy Magland 97 contactForce?: Float32Array; // mallet contact force at audio rate (N)
c696b9aCymbal: plate bending via per-triangle shape operators, felt centre support, stick and mallet with angle and friction, far-field microphoneJeremy Magland 98 malletPos?: Float32Array; // mallet position q (3 per frame) at frame times (m)
a78afe0Add WebGPU solver with a toggle; faster CPU solverJeremy Magland 99 backend?: string; // which solver ran, e.g. 'CPU' or 'WebGPU (intel gen-12lp)'
100 fallback?: string; // why WebGPU was asked for but not used
↑↓ move↵openescclose