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
24}
26export interface Excitation {
27 u0: Float64Array; // 3n initial displacement from rest
28 v0: Float64Array; // 3n initial velocity
29 // External force F(t) = shape * F0 * 0.5 (1 - cos(2 pi t / tau)), 0 <= t <= tau
30 force?: { shape: Float64Array; F0: number; tau: number };
2cd36faBead drum: hex-lattice round head, felt mallet contact, top view and cross-section; shared instrument pageJeremy Magland 31 // A mallet: point mass moving along dir, touching the beads through a felt
32 // spring with force K * delta^p, delta = s - sum_i w_i (x_i - rest_i) . dir.
33 // Starts at s = 0 (just touching the undeformed surface) with speed v0 along dir.
34 mallet?: Mallet;
35}
37export interface Mallet {
38 weights: Float64Array; // n, sums to 1 (contact patch)
39 dir: [number, number, number]; // unit
40 mass: number; // kg
41 K: number; // N / m^p
42 p: number;
43 v0: number; // m/s, > 0 toward the surface
4a8abcfString of beads: 3D bead-spring solver, control panel, waveform, spectrogram, wav, displacement viewerJeremy Magland 44}
46export interface SimOptions {
47 duration: number; // s
48 fs: number; // audio sample rate (Hz)
49 cfl: number; // fraction of the leapfrog stability limit 2/omega_max
50 frameRate: number; // displacement frames per second
51 pickup: Float64Array; // 3n weights; audio = sum w . acceleration
52}
54export interface SimResult {
55 audio: Float32Array; // pickup acceleration (m/s^2) at fs
56 fs: number;
57 frames: Float32Array; // nFrames x 3n displacement from rest
58 frameTimes: Float64Array;
59 energy: Float64Array; // mechanical energy above equilibrium at frame times (J)
60 balance: Float64Array; // E + dissipated - work_in - E0 at frame times (J)
61 dt: number;
62 stepsPerSample: number;
63 omegaMax: number;
64 wallSeconds: number;
65 maxStretch: number; // largest |l - L0| / L0 seen, at frame times
2cd36faBead drum: hex-lattice round head, felt mallet contact, top view and cross-section; shared instrument pageJeremy Magland 66 contactForce?: Float32Array; // mallet contact force at audio rate (N)
67 malletPos?: Float32Array; // mallet position s along dir at frame times (m)