// Interactive cross-section of the shallow spherical cap: radius, rise, and // thickness sliders, with the osculating sphere drawn dashed and the derived // quantities (curvature radius Rs, bending stiffness D) reported. Drawn at // true aspect ratio, because the point of the figure is how shallow the // shell actually is. import { useState } from 'react'; import { useCanvas, drawFrame, PLOT_COLORS } from '../../components/plots/canvasUtils'; import { Figure, FigControls, FigSlider } from '../figparts'; const HEIGHT = 250; export default function GeometryFig() { const [a, setA] = useState(0.23); const [rise, setRise] = useState(0.04); const [hmm, setHmm] = useState(1.0); // thickness in mm const Rs = (a * a) / (2 * rise); const E = 1.1e11; const nu = 0.33; const h = hmm * 1e-3; const D = (E * h * h * h) / (12 * (1 - nu * nu)); const ref = useCanvas( (ctx, w, hpx) => { drawFrame(ctx, w, hpx); const scale = (w - 60) / (2 * 0.36); // fixed scale so resizing the shell reads const cx = w / 2; const baseY = hpx - 70; const px = (x: number) => cx + x * scale; const py = (z: number) => baseY - z * scale; // osculating sphere, dashed: center on the axis at z = rise - Rs ctx.strokeStyle = 'rgba(139, 147, 161, 0.55)'; ctx.setLineDash([5, 5]); ctx.beginPath(); ctx.arc(px(0), py(rise - Rs), Rs * scale, 0, 2 * Math.PI); ctx.stroke(); ctx.setLineDash([]); // the cap itself: z(r) = rise (1 - r^2/a^2), the shallow form the model uses ctx.strokeStyle = '#c9a227'; ctx.lineWidth = Math.max(2, h * scale); ctx.beginPath(); const N = 90; for (let i = 0; i <= N; i++) { const r = -a + (2 * a * i) / N; const z = rise * (1 - (r * r) / (a * a)); if (i === 0) ctx.moveTo(px(r), py(z)); else ctx.lineTo(px(r), py(z)); } ctx.stroke(); ctx.lineWidth = 1; // rise marker ctx.strokeStyle = PLOT_COLORS.trace; ctx.beginPath(); ctx.moveTo(px(0), py(0)); ctx.lineTo(px(0), py(rise)); ctx.stroke(); ctx.fillStyle = PLOT_COLORS.trace; ctx.font = '11px system-ui'; ctx.textAlign = 'left'; ctx.fillText(`rise ${(rise * 100).toFixed(1)} cm`, px(0) + 6, py(rise / 2)); // radius marker ctx.strokeStyle = PLOT_COLORS.axis; ctx.beginPath(); ctx.moveTo(px(0), baseY + 14); ctx.lineTo(px(a), baseY + 14); ctx.stroke(); ctx.fillStyle = PLOT_COLORS.axis; ctx.textAlign = 'center'; ctx.fillText(`a = ${(a * 100).toFixed(1)} cm`, px(a / 2), baseY + 28); // readouts ctx.textAlign = 'left'; ctx.fillStyle = '#d6dae2'; ctx.fillText( `curvature radius Rs = a² / (2·rise) = ${Rs.toFixed(2)} m`, 14, 20, ); ctx.fillText( `bending stiffness D = E h³ / 12(1−ν²) = ${D.toFixed(3)} N·m`, 14, 38, ); ctx.fillStyle = PLOT_COLORS.axis; ctx.fillText('drawn to true scale; dashes: the sphere the cap sits on', 14, 56); }, [a, rise, hmm, Rs, D, h], HEIGHT, ); return (
The whole cymbal, cup and bow together, is replaced by one spherical cap: radius{' '} a, a small rise at the center, uniform thickness h. The rise fixes a single radius of curvature R s, and that one number carries all of the shell's “shellness”: flatten the rise toward zero and the model degenerates to a flat plate, whose low modes are much softer. Note how little curvature is involved; this shallowness is what licenses the von Kármán equations of the next section. } > `${(v * 100).toFixed(1)} cm`} onChange={setA} /> `${(v * 100).toFixed(1)} cm`} onChange={setRise} /> `${v.toFixed(2)} mm`} onChange={setHmm} />
); }