/ proof-of-concept / steelsim41
Sign in
proof-of-concept / steelsim41
Add a dented 16 inch crash preset
A dozen seeded Gaussian dents of 18 to 32 mm radius and 1 to 2 mm height scattered over the bow, plus a faint hammering field off the bell.
Jeremy Magland <jeremy.magland@gmail.com> committed commit 6edbaa36e3eb parent 1ee087e Browse files
2 changed files+42−1
README.mdmodified+1−1View file
@@ -19,7 +19,7 @@ Requires Node 20 or later and a browser with WebGPU (Chrome or Edge 113+; Firefo
1919
2020 The sidebar has three parts: the design script, the strike and simulation parameters, and the controls. The main area shows the plate (2D color map or a lit 3D height field; drag to orbit, wheel to zoom), the movie and playback toolbar, and the spectrogram of the listener signal.
2121
22-**Design script.** Pick a preset from the dropdown (a flat steel rectangle by default; a bowed rectangle, a flat disc on a stand, a 16 inch crash, a 20 inch ride, an ellipse with a twist, an 18 inch china) and edit it freely; the script is compiled as you type (or with Ctrl+Enter) and the view shows the resulting stress-free shape, colored by height or by thickness. Errors are reported under the script, and a summary lists the bounding box, the material, the thickness range, the mass, the grid, the profile's peak-to-peak height and largest slope (with a warning above the shallow-shell range), the mount, and the losses. Revert restores the selected preset.
22+**Design script.** Pick a preset from the dropdown (a flat steel rectangle by default; a bowed rectangle, a flat disc on a stand, a 16 inch crash, the same crash with a dozen dents, a 20 inch ride, an ellipse with a twist, an 18 inch china) and edit it freely; the script is compiled as you type (or with Ctrl+Enter) and the view shows the resulting stress-free shape, colored by height or by thickness. Errors are reported under the script, and a summary lists the bounding box, the material, the thickness range, the mass, the grid, the profile's peak-to-peak height and largest slope (with a warning above the shallow-shell range), the mount, and the losses. Revert restores the selected preset.
2323
2424 The script is a plain JavaScript function body that returns the design object. All lengths are meters; `inch` and `mm` are conversion constants. Every field function receives `(x, y, r, theta)`: the point relative to the center of the bounding box, its distance from the center, and its angle from the x axis.
2525
src/presets.tsmodified+41−0View file
@@ -77,6 +77,46 @@ return {
7777 };
7878 `;
7979
80+const crashDented = `// A 16 inch crash that has been through a lot: the same bronze, taper,
81+// bow, and bell as the clean crash, plus a dozen dents scattered over the
82+// bow and a faint hammering texture. The dents are Gaussian bumps of a few
83+// centimeters (broad compared with the 8 mm grid) and a millimeter or two
84+// in height, up or down; change the seed for a different set. Dents break
85+// the symmetry of the disc, split the degenerate mode pairs, and give the
86+// cymbal a less pure, more trashy tone.
87+const D = 16 * inch, R = D / 2;
88+const bellR = 60 * mm, bellH = 12 * mm, bowH = 16 * mm;
89+// A small seeded generator, so the dents are the same every time.
90+let seed = 7;
91+const rnd = () => { seed = (seed * 1664525 + 1013904223) % 4294967296; return seed / 4294967296; };
92+const dents = [];
93+for (let k = 0; k < 12; k++) {
94+ const rr = bellR + 25 * mm + (R - bellR - 45 * mm) * rnd(); // on the bow, clear of the bell and the edge
95+ const th = 2 * Math.PI * rnd();
96+ dents.push({
97+ x: rr * Math.cos(th), y: rr * Math.sin(th),
98+ radius: (18 + 14 * rnd()) * mm,
99+ height: (rnd() < 0.5 ? -1 : 1) * (0.8 + 1.4 * rnd()) * mm,
100+ });
101+}
102+const hammer = noise2d(3, 40 * mm); // unit RMS, correlation length 40 mm
103+return {
104+ name: "16 inch crash, dented",
105+ material: { E: 110e9, nu: 0.34, rho: 8800 },
106+ bounds: { width: D, height: D },
107+ inside: circle(D, 12 * mm),
108+ thickness: (x, y, r) => lerp(1.4 * mm, 0.8 * mm, clamp((r - bellR) / (R - bellR), 0, 1)),
109+ profile: (x, y, r) => {
110+ let z = bowH * (1 - (r / R) ** 2) + dome(r, bellR, bellH);
111+ for (const d of dents) z += bump(Math.hypot(x - d.x, y - d.y), d.radius, d.height);
112+ z += 0.3 * mm * hammer(x, y) * smoothstep(bellR, bellR + 30 * mm, r); // no hammering on the bell
113+ return z;
114+ },
115+ mount: { radius: 20 * mm, stiffness: 2e4, damping: 5 },
116+ loss: { sigma0: 0.6, sigma1: 2.5e-4, sigmaIn: 20 },
117+};
118+`;
119+
80120 const ride20 = `// A 20 inch ride: heavier bronze, a larger bell, a flatter bow. The taper
81121 // is stronger than on the crash, and the mount is a little stiffer.
82122 const D = 20 * inch, R = D / 2;
@@ -140,6 +180,7 @@ export const PRESETS: Preset[] = [
140180 { id: "bowed-rectangle", label: "Bowed steel rectangle", source: bowedRectangle },
141181 { id: "flat-disc", label: "Flat steel disc on a stand", source: flatDisc },
142182 { id: "crash-16", label: "16 inch crash", source: crash16 },
183+ { id: "crash-16-dented", label: "16 inch crash, dented", source: crashDented },
143184 { id: "ride-20", label: "20 inch ride", source: ride20 },
144185 { id: "ellipse-twist", label: "Steel ellipse with a twist", source: ellipseTwist },
145186 { id: "china-18", label: "18 inch china", source: china18 },
↑↓ move↵openescclose