Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Interactive SDOF Vibration Simulator</title> | |
| <meta name="description" | |
| content="Interactive simulation of a damped single-degree-of-freedom (SDOF) vibration system. Visualize displacement and velocity in real-time."> | |
| <link rel="stylesheet" href="style.css"> | |
| <link rel="preconnect" href="https://fonts.googleapis.com"> | |
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | |
| <link | |
| href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Fira+Code:wght@500&display=swap" | |
| rel="stylesheet"> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <header> | |
| <h1>SDOF Vibration Simulator</h1> | |
| <p>Explore the dynamics of a Single-Degree-of-Freedom system. Adjust parameters to see real-time response. | |
| </p> | |
| </header> | |
| <!-- Visual Panel --> | |
| <section class="visual-panel"> | |
| <div class="diagram-container"> | |
| <!-- SVG Diagram --> | |
| <svg viewBox="0 0 480 180" width="100%" role="img" aria-label="SDOF System Diagram"> | |
| <pattern id="hatch" patternUnits="userSpaceOnUse" width="6" height="6"> | |
| <path d="M-1,1 l2,-2 M0,6 l6,-6 M5,7 l2,-2" stroke="#4b5563" stroke-width="1" /> | |
| </pattern> | |
| <rect x="0" y="150" width="480" height="20" fill="url(#hatch)" /> | |
| <rect x="10" y="40" width="20" height="110" fill="#111827" stroke="#111827" stroke-width="2" /> | |
| <g transform="translate(30,90)"> | |
| <line x1="0" y1="0" x2="20" y2="0" stroke="#111827" stroke-width="2" /> | |
| <polyline points="20,0 30,-10 40,10 50,-10 60,10 70,-10 80,10 90,-10 100,0" fill="none" | |
| stroke="#111827" stroke-width="2" /> | |
| <line x1="100" y1="0" x2="120" y2="0" stroke="#111827" stroke-width="2" /> | |
| </g> | |
| <g transform="translate(30,120)"> | |
| <line x1="0" y1="0" x2="20" y2="0" stroke="#111827" stroke-width="2" /> | |
| <rect x="20" y="-8" width="25" height="16" fill="none" stroke="#111827" stroke-width="2" /> | |
| <line x1="45" y1="0" x2="70" y2="0" stroke="#111827" stroke-width="2" /> | |
| <line x1="70" y1="-8" x2="70" y2="8" stroke="#111827" stroke-width="2" /> | |
| <line x1="70" y1="-8" x2="80" y2="-8" stroke="#111827" stroke-width="2" /> | |
| <line x1="70" y1="8" x2="80" y2="8" stroke="#111827" stroke-width="2" /> | |
| <line x1="80" y1="-8" x2="80" y2="8" stroke="#111827" stroke-width="2" /> | |
| <line x1="80" y1="0" x2="120" y2="0" stroke="#111827" stroke-width="2" /> | |
| </g> | |
| <rect x="150" y="70" width="110" height="70" fill="#ffffff" stroke="#111827" stroke-width="2" /> | |
| <circle cx="175" cy="145" r="8" fill="#ffffff" stroke="#111827" stroke-width="2" /> | |
| <circle cx="235" cy="145" r="8" fill="#ffffff" stroke="#111827" stroke-width="2" /> | |
| <defs> | |
| <marker id="arrow" markerWidth="8" markerHeight="8" refX="7" refY="4" orient="auto"> | |
| <path d="M0,0 L8,4 L0,8 z" fill="#111827" /> | |
| </marker> | |
| </defs> | |
| <line x1="150" y1="55" x2="230" y2="55" stroke="#111827" stroke-width="2" | |
| marker-end="url(#arrow)" /> | |
| <text x="232" y="59" font-size="14" font-family="sans-serif">u(t)</text> | |
| <line x1="260" y1="105" x2="330" y2="105" stroke="#111827" stroke-width="2" | |
| marker-end="url(#arrow)" /> | |
| <text x="332" y="93" font-size="14" font-family="sans-serif">F(t)</text> | |
| </svg> | |
| </div> | |
| </section> | |
| <!-- Theory Panel --> | |
| <section class="theory-panel"> | |
| <h2>Theory & Guide</h2> | |
| <div class="theory-content"> | |
| <div class="theory-block"> | |
| <h3>System Parameters</h3> | |
| <ul> | |
| <li><strong>m (Mass):</strong> Inertia of the system (kg).</li> | |
| <li><strong>k (Stiffness):</strong> Resistance to deformation (N/m).</li> | |
| <li><strong>c (Damping):</strong> Energy dissipation coefficient (N·s/m).</li> | |
| </ul> | |
| </div> | |
| <div class="theory-block"> | |
| <h3>Forcing</h3> | |
| <ul> | |
| <li><strong>F₀ (Amplitude):</strong> Magnitude of external force (N).</li> | |
| <li><strong>p (Frequency):</strong> Frequency of external force (rad/s).</li> | |
| </ul> | |
| </div> | |
| <div class="theory-block"> | |
| <h3>Fundamental Equations</h3> | |
| <p>Natural Frequency: <span class="math">ωₙ = √(k/m)</span></p> | |
| <p>Damping Ratio: <span class="math">ζ = c / (2√(km))</span></p> | |
| </div> | |
| <div class="theory-block"> | |
| <h3>Damping Regimes</h3> | |
| <ul> | |
| <li><strong>Underdamped (ζ < 1):</strong> Oscillates with decaying amplitude.</li> | |
| <li><strong>Critically Damped (ζ = 1):</strong> Fastest return to equilibrium without | |
| oscillation.</li> | |
| <li><strong>Overdamped (ζ > 1):</strong> Slow return to equilibrium without oscillation.</li> | |
| </ul> | |
| </div> | |
| </div> | |
| <div class="theory-footer"> | |
| <strong>Simulation Tip:</strong> For <em>Free Vibration</em>, set <strong>F₀ = 0</strong> and adjust | |
| Initial Displacement (<strong>u₀</strong>) or Velocity (<strong>v₀</strong>). | |
| </div> | |
| </section> | |
| <main class="dashboard"> | |
| <!-- Controls Panel (Left Column) --> | |
| <section class="controls-panel"> | |
| <div class="control-group"> | |
| <label for="mass-slider">Mass (m)</label> | |
| <div class="slider-wrapper"> | |
| <input type="range" id="mass-slider" min="0.5" max="5" step="0.1" value="1"> | |
| <span class="slider-value" id="mass-val">1.0</span> | |
| </div> | |
| </div> | |
| <div class="control-group"> | |
| <label for="stiffness-slider">Stiffness (k)</label> | |
| <div class="slider-wrapper"> | |
| <input type="range" id="stiffness-slider" min="20" max="800" step="10" value="100"> | |
| <span class="slider-value" id="stiffness-val">100</span> | |
| </div> | |
| </div> | |
| <div class="control-group"> | |
| <label for="damping-slider">Damping (c)</label> | |
| <div class="slider-wrapper"> | |
| <input type="range" id="damping-slider" min="0" max="60" step="0.5" value="5"> | |
| <span class="slider-value" id="damping-val">5.0</span> | |
| </div> | |
| </div> | |
| <div class="control-group"> | |
| <label for="force-slider">Forcing Amp (F0)</label> | |
| <div class="slider-wrapper"> | |
| <input type="range" id="force-slider" min="0" max="80" step="1" value="10"> | |
| <span class="slider-value" id="force-val">10</span> | |
| </div> | |
| </div> | |
| <div class="control-group"> | |
| <label for="p-slider">Forcing Freq (p)</label> | |
| <div class="slider-wrapper"> | |
| <input type="range" id="p-slider" min="0.5" max="20" step="0.5" value="5"> | |
| <span class="slider-value" id="p-val">5.0</span> | |
| </div> | |
| </div> | |
| <div class="control-group"> | |
| <label for="u0-slider">Initial Disp. (u0)</label> | |
| <div class="slider-wrapper"> | |
| <input type="range" id="u0-slider" min="-5" max="5" step="0.1" value="0"> | |
| <span class="slider-value" id="u0-val">0.0</span> | |
| </div> | |
| </div> | |
| <div class="control-group"> | |
| <label for="v0-slider">Initial Vel. (v0)</label> | |
| <div class="slider-wrapper"> | |
| <input type="range" id="v0-slider" min="-10" max="10" step="0.1" value="0"> | |
| <span class="slider-value" id="v0-val">0.0</span> | |
| </div> | |
| </div> | |
| <!-- Calculated Stats (Moved inside Controls Panel) --> | |
| <div class="stats-panel" | |
| style="margin-top: 1.5rem; border-top: 1px solid var(--border); padding-top: 1.5rem;"> | |
| <div class="stat-card"> | |
| <span class="stat-label">Natural Frequency (ωn)</span> | |
| <span class="stat-value" id="omega-n-val">--</span> | |
| </div> | |
| <div class="stat-card"> | |
| <span class="stat-label">Damping Ratio (ζ)</span> | |
| <span class="stat-value" id="zeta-val">--</span> | |
| </div> | |
| <div class="stat-card"> | |
| <span class="stat-label">Regime</span> | |
| <span class="stat-value highlight" id="regime-val">--</span> | |
| </div> | |
| <div class="stat-card"> | |
| <span class="stat-label">Peak Disp.</span> | |
| <span class="stat-value" id="peak-disp-val">--</span> | |
| </div> | |
| <div class="stat-card"> | |
| <span class="stat-label">Peak Vel.</span> | |
| <span class="stat-value" id="peak-vel-val">--</span> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Charts Panel (Bottom Right) --> | |
| <section class="charts-panel"> | |
| <div class="equation-container"> | |
| <h3>System Equation</h3> | |
| <div id="math-equation"></div> | |
| <div id="math-solution"></div> | |
| </div> | |
| <div class="chart-container"> | |
| <h3>Displacement u(t)</h3> | |
| <canvas id="disp-chart"></canvas> | |
| </div> | |
| <div class="chart-container"> | |
| <h3>Velocity u'(t)</h3> | |
| <canvas id="vel-chart"></canvas> | |
| </div> | |
| </section> | |
| </main> | |
| </div> | |
| <script src="script.js"></script> | |
| </body> | |
| </html> |