/ proof-of-concept / toy-instruments
Sign in
proof-of-concept / toy-instruments
toy-instruments / src / sim / types.ts
95 lines · 3.9 KBBlameHistoryRaw
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 bending?: Bending;
27// Plate bending (Poisson ratio built into M). Hinge e measures the dihedral
28// angle across edge (e0, e1) shared by triangles (e0, e1, w0) and (e1, e0, w1);
29// phi_e = sign_e (theta_e - theta0_e) is its change, positive when the surface
30// folds toward its upward normal. Triangle t holds up to three hinges
31// (-1 = free edge) and has energy 1/2 phi^T M phi; M is the plate energy
32// A D/2 [(tr S)^2 - 2 (1 - nu) det S] of the shape operator
33// S = sum_e phi_e l_e / (2A) m_e m_e^T, condensed over free edges (no moment there).
34// Damping: the moments use phi + 2 sigma1 dphi/dt (Rayleigh, sigma1 omega^2).
35export interface Bending {
36 w0: Int32Array;
37 w1: Int32Array;
38 e0: Int32Array;
39 e1: Int32Array;
40 sign: Float64Array;
41 theta0: Float64Array;
42 tri: Int32Array; // 3 per triangle
43 M: Float64Array; // 9 per triangle
44 sigma1: number;
47export interface Excitation {
48 u0: Float64Array; // 3n initial displacement from rest
49 v0: Float64Array; // 3n initial velocity
50 // External force F(t) = shape * F0 * 0.5 (1 - cos(2 pi t / tau)), 0 <= t <= tau
51 force?: { shape: Float64Array; F0: number; tau: number };
52 // A mallet or stick: point mass q in 3D touching a patch of beads.
53 // Normal force K delta^p with delta = (q - sum_i w_i (x_i - rest_i)) . normal;
54 // Coulomb friction mu * normal force against tangential slip.
55 // Starts at q = 0 (just touching the undeformed patch) with velocity vel0.
56 mallet?: Mallet;
59export interface Mallet {
60 weights: Float64Array; // n, sums to 1 (contact patch)
61 normal: [number, number, number]; // unit, pointing into the surface
62 vel0: [number, number, number]; // m/s; its component along normal must be > 0
63 mass: number; // kg
64 K: number; // N / m^p
65 p: number;
66 mu: number; // friction coefficient (0 = frictionless)
67 // no contact once the mallet has slid this far sideways from the patch (m); default unlimited
68 reach?: number;
71export interface SimOptions {
72 duration: number; // s
73 fs: number; // audio sample rate (Hz)
74 cfl: number; // fraction of the leapfrog stability limit 2/omega_max
75 frameRate: number; // displacement frames per second
76 pickup: Float64Array; // 3n weights; audio = sum w . acceleration
77 // optional per-bead delay in samples (a microphone): bead i's term arrives delay[i] later
78 pickupDelay?: Float64Array;
81export interface SimResult {
82 audio: Float32Array; // pickup acceleration (m/s^2) at fs
83 fs: number;
84 frames: Float32Array; // nFrames x 3n displacement from rest
85 frameTimes: Float64Array;
86 energy: Float64Array; // mechanical energy above equilibrium at frame times (J)
87 balance: Float64Array; // E + dissipated - work_in - E0 at frame times (J)
88 dt: number;
89 stepsPerSample: number;
90 omegaMax: number;
91 wallSeconds: number;
92 maxStretch: number; // largest |l - L0| / L0 of bead-to-bead springs, at frame times
93 contactForce?: Float32Array; // mallet contact force at audio rate (N)
94 malletPos?: Float32Array; // mallet position q (3 per frame) at frame times (m)
↑↓ move↵openescclose