{"id":81,"date":"2026-05-20T17:33:46","date_gmt":"2026-05-20T17:33:46","guid":{"rendered":"https:\/\/flowxiom.com\/?p=81"},"modified":"2026-05-20T17:35:33","modified_gmt":"2026-05-20T17:35:33","slug":"standing-wave","status":"publish","type":"post","link":"https:\/\/flowxiom.com\/index.php\/2026\/05\/20\/standing-wave\/","title":{"rendered":"Standing Wave"},"content":{"rendered":"\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Standing Wave Formation Simulator<\/title>\n    <style>\n        body {\n            font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif;\n            background-color: #f4f7f6;\n            margin: 0;\n            padding: 20px;\n            display: flex;\n            flex-direction: column;\n            align-items: center;\n            color: #333;\n        }\n\n        .container {\n            background: white;\n            padding: 25px;\n            border-radius: 12px;\n            box-shadow: 0 6px 20px rgba(0, 0, 0, 0.08);\n            max-width: 900px;\n            width: 100%;\n        }\n\n        h1 {\n            text-align: center;\n            color: #2c3e50;\n            margin-top: 0;\n        }\n\n        .legend {\n            display: flex;\n            justify-content: center;\n            gap: 20px;\n            margin-bottom: 10px;\n            font-size: 14px;\n            font-weight: bold;\n        }\n\n        .legend span {\n            display: flex;\n            align-items: center;\n            gap: 5px;\n        }\n\n        .color-box {\n            width: 20px;\n            height: 4px;\n            display: inline-block;\n        }\n\n        canvas {\n            background: #1e1e1e;\n            border-radius: 8px;\n            display: block;\n            margin: 0 auto 20px;\n            width: 100%;\n            max-width: 850px;\n        }\n\n        .panel-grid {\n            display: grid;\n            grid-template-columns: 1fr 1fr;\n            gap: 20px;\n        }\n\n        .controls,\n        .results {\n            background: #f8f9fa;\n            padding: 20px;\n            border-radius: 8px;\n            border: 1px solid #e9ecef;\n        }\n\n        .control-group {\n            margin-bottom: 15px;\n        }\n\n        label {\n            display: block;\n            font-weight: bold;\n            margin-bottom: 8px;\n            color: #495057;\n        }\n\n        input[type=\"range\"] {\n            width: 100%;\n            cursor: pointer;\n        }\n\n        .btn-group {\n            display: flex;\n            gap: 10px;\n        }\n\n        button {\n            flex: 1;\n            padding: 8px 0;\n            cursor: pointer;\n            border: 1px solid #ced4da;\n            background: white;\n            border-radius: 4px;\n            font-weight: bold;\n            transition: 0.2s;\n        }\n\n        button.active {\n            background: #0d6efd;\n            color: white;\n            border-color: #0d6efd;\n        }\n\n        .results p {\n            margin: 8px 0;\n            font-size: 16px;\n        }\n\n        .highlight {\n            font-weight: bold;\n            color: #0d6efd;\n            font-size: 1.1em;\n        }\n    <\/style>\n<\/head>\n\n<body>\n\n    <div class=\"container\">\n        <h1>Standing Wave Physics Demonstration<\/h1>\n\n        <div class=\"legend\">\n            <span>\n                <div class=\"color-box\" style=\"background: #4cc9f0;\"><\/div> Right-traveling Wave (Incident)\n            <\/span>\n            <span>\n                <div class=\"color-box\" style=\"background: #f72585;\"><\/div> Left-traveling Wave (Reflected)\n            <\/span>\n            <span>\n                <div class=\"color-box\" style=\"background: #ffffff; height: 6px;\"><\/div> Standing Wave (Superposition)\n            <\/span>\n        <\/div>\n\n        <canvas id=\"waveCanvas\" width=\"850\" height=\"300\"><\/canvas>\n\n        <div class=\"panel-grid\">\n            <div class=\"controls\">\n                <div class=\"control-group\">\n                    <label>Harmonic Number (n): Determines antinodes<\/label>\n                    <div class=\"btn-group\" id=\"n-buttons\">\n                        <button class=\"active\" data-n=\"1\">n = 1<\/button>\n                        <button data-n=\"2\">n = 2<\/button>\n                        <button data-n=\"3\">n = 3<\/button>\n                        <button data-n=\"4\">n = 4<\/button>\n                        <button data-n=\"5\">n = 5<\/button>\n                    <\/div>\n                <\/div>\n                <div class=\"control-group\">\n                    <label>Amplitude (A): <span id=\"amp-val\">1.0<\/span> m<\/label>\n                    <input type=\"range\" id=\"amp-slider\" min=\"0.2\" max=\"2.0\" step=\"0.1\" value=\"1.0\">\n                <\/div>\n                <div class=\"control-group\">\n                    <label>Wave Speed (v): <span id=\"vel-val\">20<\/span> m\/s<\/label>\n                    <input type=\"range\" id=\"vel-slider\" min=\"5\" max=\"50\" step=\"1\" value=\"20\">\n                <\/div>\n            <\/div>\n\n            <div class=\"results\">\n                <h3 style=\"margin-top: 0; color: #2c3e50;\">Real-time Physics Parameters<\/h3>\n                <p>Fixed String Length (L): <strong>10.00 m<\/strong><\/p>\n                <p>Wavelength (\u03bb = 2L\/n): <span id=\"res-lambda\" class=\"highlight\">20.00<\/span> m<\/p>\n                <p>Frequency (f = v\/\u03bb): <span id=\"res-freq\" class=\"highlight\">1.00<\/span> Hz<\/p>\n                <p>Period (T = 1\/f): <span id=\"res-period\" class=\"highlight\">1.00<\/span> s<\/p>\n                <p style=\"margin-top: 15px; font-size: 14px; color: #666;\">\n                    * <strong>Nodes<\/strong>: Points with consistently 0 amplitude (yellow dots).<br>\n                    * <strong>Antinodes<\/strong>: Points with maximum amplitude (green dots).\n                <\/p>\n            <\/div>\n        <\/div>\n    <\/div>\n\n    <script>\n        const canvas = document.getElementById('waveCanvas');\n        const ctx = canvas.getContext('2d');\n\n        \/\/ UI Elements\n        const ampSlider = document.getElementById('amp-slider');\n        const velSlider = document.getElementById('vel-slider');\n        const ampVal = document.getElementById('amp-val');\n        const velVal = document.getElementById('vel-val');\n        const nButtons = document.querySelectorAll('#n-buttons button');\n\n        \/\/ Result Display\n        const resLambda = document.getElementById('res-lambda');\n        const resFreq = document.getElementById('res-freq');\n        const resPeriod = document.getElementById('res-period');\n\n        \/\/ Physics Parameters\n        const L = 10; \/\/ String length 10m\n        let n = 1;    \/\/ Harmonic number\n        let A = 1.0;  \/\/ Amplitude\n        let v = 20;   \/\/ Wave speed\n\n        let time = 0; \/\/ Animation time\n        let animationId;\n\n        \/\/ Bind button events\n        nButtons.forEach(btn => {\n            btn.addEventListener('click', (e) => {\n                nButtons.forEach(b => b.classList.remove('active'));\n                e.target.classList.add('active');\n                n = parseInt(e.target.getAttribute('data-n'));\n                updateCalculations();\n            });\n        });\n\n        \/\/ Bind slider events\n        ampSlider.addEventListener('input', (e) => {\n            A = parseFloat(e.target.value);\n            ampVal.textContent = A.toFixed(1);\n        });\n\n        velSlider.addEventListener('input', (e) => {\n            v = parseFloat(e.target.value);\n            velVal.textContent = v.toFixed(0);\n            updateCalculations();\n        });\n\n        \/\/ Calculate derived physics quantities and update UI\n        function updateCalculations() {\n            const lambda = (2 * L) \/ n;\n            const freq = v \/ lambda;\n            const period = 1 \/ freq;\n\n            resLambda.textContent = lambda.toFixed(2);\n            resFreq.textContent = freq.toFixed(2);\n            resPeriod.textContent = period.toFixed(2);\n        }\n\n        \/\/ Core drawing and physics logic\n        function draw() {\n            ctx.clearRect(0, 0, canvas.width, canvas.height);\n\n            const width = canvas.width;\n            const height = canvas.height;\n            const centerY = height \/ 2;\n            const scaleX = width \/ L;\n            const scaleY = 40; \/\/ Y-axis pixel scale ratio\n\n            \/\/ Draw equilibrium position dashed line\n            ctx.beginPath();\n            ctx.strokeStyle = '#555';\n            ctx.setLineDash([5, 5]);\n            ctx.moveTo(0, centerY);\n            ctx.lineTo(width, centerY);\n            ctx.stroke();\n            ctx.setLineDash([]);\n\n            \/\/ Physics formula parameters\n            const lambda = (2 * L) \/ n;\n            const k = (2 * Math.PI) \/ lambda; \/\/ Wave number\n            const omega = (2 * Math.PI * v) \/ lambda; \/\/ Angular frequency\n\n            ctx.lineWidth = 2;\n\n            \/\/ Path preparation\n            ctx.beginPath(); const path1 = new Path2D(); \/\/ Incident wave (Right)\n            ctx.beginPath(); const path2 = new Path2D(); \/\/ Reflected wave (Left)\n            ctx.beginPath(); const pathSum = new Path2D(); \/\/ Standing wave (Superposition)\n\n            \/\/ Iterate through X-axis pixels for calculation\n            for (let px = 0; px <= width; px += 2) {\n                const x = px \/ scaleX; \/\/ Map pixel coordinates to physical coordinates (0 - 10m)\n\n                \/\/ Wave equation\n                \/\/ y1 = A * sin(kx - \u03c9t)\n                const y1 = A * Math.sin(k * x - omega * time);\n                \/\/ y2 = A * sin(kx + \u03c9t)\n                const y2 = A * Math.sin(k * x + omega * time);\n                \/\/ Superposition ySum = y1 + y2 = 2A * sin(kx) * cos(\u03c9t)\n                const ySum = y1 + y2;\n\n                \/\/ Convert back to pixel coordinates\n                const py1 = centerY - y1 * scaleY;\n                const py2 = centerY - y2 * scaleY;\n                const pySum = centerY - ySum * scaleY;\n\n                if (px === 0) {\n                    path1.moveTo(px, py1); path2.moveTo(px, py2); pathSum.moveTo(px, pySum);\n                } else {\n                    path1.lineTo(px, py1); path2.lineTo(px, py2); pathSum.lineTo(px, pySum);\n                }\n            }\n\n            \/\/ Draw two interfering waves (semi-transparent)\n            ctx.strokeStyle = 'rgba(76, 201, 240, 0.6)'; \/\/ Blue\n            ctx.stroke(path1);\n            ctx.strokeStyle = 'rgba(247, 37, 133, 0.6)'; \/\/ Pink\n            ctx.stroke(path2);\n\n            \/\/ Draw standing wave (solid)\n            ctx.lineWidth = 4;\n            ctx.strokeStyle = '#ffffff';\n            ctx.stroke(pathSum);\n\n            \/\/ Mark Nodes and Antinodes\n            for (let i = 0; i <= n; i++) {\n                \/\/ Node x = i * (\u03bb\/2) = i * (L\/n)\n                const nodeX = i * (L \/ n);\n                const nodePx = nodeX * scaleX;\n                ctx.beginPath();\n                ctx.arc(nodePx, centerY, 6, 0, Math.PI * 2);\n                ctx.fillStyle = '#ffb703'; \/\/ Yellow node\n                ctx.fill();\n\n                \/\/ Antinode x = (i + 0.5) * (L\/n)\n                if (i < n) {\n                    const antiNodeX = (i + 0.5) * (L \/ n);\n                    const antiNodePx = antiNodeX * scaleX;\n                    \/\/ Antinode Y coordinate depends on time vibration: 2A * cos(\u03c9t)\n                    const currentAmp = 2 * A * Math.cos(omega * time);\n                    \/\/ Here we draw points for antinode to indicate its range of motion (or current position)\n                    \/\/ Draw only current position to keep animation smooth\n                    ctx.beginPath();\n                    ctx.arc(antiNodePx, centerY - (currentAmp * scaleY * Math.sin(k * antiNodeX)), 5, 0, Math.PI * 2);\n                    ctx.fillStyle = '#06d6a0'; \/\/ Green antinode\n                    ctx.fill();\n                }\n            }\n\n            \/\/ Time step\n            time += 0.02;\n            animationId = requestAnimationFrame(draw);\n        }\n\n        \/\/ Initialization\n        updateCalculations();\n        draw();\n    <\/script>\n\n<\/body>\n\n<\/html>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Adjust frequencies and watch nodes form in real time to see how standing waves capture and store energy.<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[6],"tags":[],"class_list":["post-81","post","type-post","status-publish","format-standard","hentry","category-visual-learning-tools"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/flowxiom.com\/index.php\/wp-json\/wp\/v2\/posts\/81","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/flowxiom.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/flowxiom.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/flowxiom.com\/index.php\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/flowxiom.com\/index.php\/wp-json\/wp\/v2\/comments?post=81"}],"version-history":[{"count":1,"href":"https:\/\/flowxiom.com\/index.php\/wp-json\/wp\/v2\/posts\/81\/revisions"}],"predecessor-version":[{"id":82,"href":"https:\/\/flowxiom.com\/index.php\/wp-json\/wp\/v2\/posts\/81\/revisions\/82"}],"wp:attachment":[{"href":"https:\/\/flowxiom.com\/index.php\/wp-json\/wp\/v2\/media?parent=81"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/flowxiom.com\/index.php\/wp-json\/wp\/v2\/categories?post=81"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/flowxiom.com\/index.php\/wp-json\/wp\/v2\/tags?post=81"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}