小球动量实验edit icon

创建者:
用户zdlDCoL7
Fork(复制)
下载
嵌入
BUG反馈
index.html
style.css
index.js
index.html
            
            <!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>弹性碰撞演示</title>
    <style>
        body {
            font-family: 'Microsoft YaHei', sans-serif;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
            background-color: #f5f5f5;
        }
        h1 {
            color: #2c3e50;
            text-align: center;
        }
        .container {
            display: flex;
            flex-direction: column;
            gap: 20px;
        }
        .control-panel {
            background-color: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
        .slider-container {
            margin-bottom: 15px;
        }
        label {
            display: inline-block;
            width: 120px;
            font-weight: bold;
        }
        input[type="range"] {
            width: 300px;
            vertical-align: middle;
        }
        .value-display {
            display: inline-block;
            width: 60px;
            text-align: right;
            margin-left: 10px;
        }
        button {
            background-color: #3498db;
            color: white;
            border: none;
            padding: 8px 16px;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
            margin-right: 10px;
        }
        button:hover {
            background-color: #2980b9;
        }
        .animation-area {
            background-color: white;
            height: 200px;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
            position: relative;
            overflow: hidden;
        }
        .ball {
            position: absolute;
            border-radius: 50%;
            width: 50px;//
            height: 50px;
            top: 75px;
            text-align: center;
            line-height: 50px;
            color: white;
            font-weight: bold;
        }
        #ball1 {
            background-color: #e74c3c;
            left: 100px;
        }
        #ball2 {
            background-color: #2ecc71;
            left: 400px;
        }
        .results {
            background-color: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
        table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 10px;
        }
        th, td {
            border: 1px solid #ddd;
            padding: 8px;
            text-align: left;
        }
        th {
            background-color: #f2f2f2;
        }
        .formula {
            background-color: #f8f9fa;
            padding: 10px;
            border-radius: 4px;
            margin-top: 15px;
            font-family: monospace;
        }
    </style>
</head>
<body>
    <h1>弹性碰撞演示</h1>
    <div class="container">
        <div class="control-panel">
            <h2>参数设置</h2>
            <div class="slider-container">
                <label for="m1">小球1质量 (kg):</label>
                <input type="range" id="m1" min="1" max="10" step="0.1" value="2">
                <span id="m1-value" class="value-display">2</span>
            </div>
            <div class="slider-container">
                <label for="m2">小球2质量 (kg):</label>
                <input type="range" id="m2" min="1" max="10" step="0.1" value="1">
                <span id="m2-value" class="value-display">1</span>
            </div>
            <div class="slider-container">
                <label for="v1">小球1初速度 (m/s):</label>
                <input type="range" id="v1" min="-10" max="10" step="0.1" value="3">
                <span id="v1-value" class="value-display">3</span>
            </div>
            <div class="slider-container">
                <label for="v2">小球2初速度 (m/s):</label>
                <input type="range" id="v2" min="-10" max="10" step="0.1" value="0">
                <span id="v2-value" class="value-display">0</span>
            </div>
            <div style="margin-top: 20px;">
                <button id="start-btn">开始碰撞</button>
                <button id="reset-btn">重置</button>
            </div>
        </div>

        <div class="animation-area">
            <div id="ball1" class="ball">m1</div>
            <div id="ball2" class="ball">m2</div>
        </div>

        <div class="results">
            <h2>计算结果</h2>
            <table>
                <tr>
                    <th>物理量</th>
                    <th>碰撞前</th>
                    <th>碰撞后</th>
                </tr>
                <tr>
                    <td>小球1速度 (m/s)</td>
                    <td id="v1-before">3.0</td>
                    <td id="v1-after">-</td>
                </tr>
                <tr>
                    <td>小球2速度 (m/s)</td>
                    <td id="v2-before">0.0</td>
                    <td id="v2-after">-</td>
                </tr>
                <tr>
                    <td>系统动量 (kg·m/s)</td>
                    <td id="p-before">6.0</td>
                    <td id="p-after">-</td>
                </tr>
                <tr>
                    <td>系统动能 (J)</td>
                    <td id="k-before">9.0</td>
                    <td id="k-after">-</td>
                </tr>
            </table>
            <div class="formula">
                <p>弹性碰撞公式:</p>
                <p>v<sub>1</sub>' = (m<sub>1</sub>-m<sub>2</sub>)v<sub>1</sub> + 2m<sub>2</sub>v<sub>2</sub> / (m<sub>1</sub>+m<sub>2</sub>)</p>
                <p>v<sub>2</sub>' = (m<sub>2</sub>-m<sub>1</sub>)v<sub>2</sub> + 2m<sub>1</sub>v<sub>1</sub> / (m<sub>1</sub>+m<sub>2</sub>)</p>
            </div>
        </div>
    </div>

    <script>
        // 获取DOM元素
        const m1Slider = document.getElementById('m1');
        const m2Slider = document.getElementById('m2');
        const v1Slider = document.getElementById('v1');
        const v2Slider = document.getElementById('v2');
        const m1Value = document.getElementById('m1-value');
        const m2Value = document.getElementById('m2-value');
        const v1Value = document.getElementById('v1-value');
        const v2Value = document.getElementById('v2-value');
        
        const ball1 = document.getElementById('ball1');
        const ball2 = document.getElementById('ball2');
        
        const v1Before = document.getElementById('v1-before');
        const v2Before = document.getElementById('v2-before');
        const v1After = document.getElementById('v1-after');
        const v2After = document.getElementById('v2-after');
        const pBefore = document.getElementById('p-before');
        const pAfter = document.getElementById('p-after');
        const kBefore = document.getElementById('k-before');
        const kAfter = document.getElementById('k-after');
        
        const startBtn = document.getElementById('start-btn');
        const resetBtn = document.getElementById('reset-btn');

        // 更新显示值
        function updateDisplayValues() {
            m1Value.textContent = m1Slider.value;
            m2Value.textContent = m2Slider.value;
            v1Value.textContent = v1Slider.value;
            v2Value.textContent = v2Slider.value;
            
            ball1.textContent = `m1=${m1Slider.value}`;
            ball2.textContent = `m2=${m2Slider.value}`;
            
            v1Before.textContent = v1Slider.value;
            v2Before.textContent = v2Slider.value;
            
            // 计算初始动量和动能
            const m1 = parseFloat(m1Slider.value);
            const m2 = parseFloat(m2Slider.value);
            const v1 = parseFloat(v1Slider.value);
            const v2 = parseFloat(v2Slider.value);
            
            const p = m1 * v1 + m2 * v2;
            const k = 0.5 * m1 * v1 * v1 + 0.5 * m2 * v2 * v2;
            
            pBefore.textContent = p.toFixed(2);
            kBefore.textContent = k.toFixed(2);
        }

        // 计算弹性碰撞后的速度
        function calculateCollision() {
            const m1 = parseFloat(m1Slider.value);
            const m2 = parseFloat(m2Slider.value);
            const v1 = parseFloat(v1Slider.value);
            const v2 = parseFloat(v2Slider.value);
            
            // 弹性碰撞公式
            const v1f = ((m1 - m2) * v1 + 2 * m2 * v2) / (m1 + m2);
            const v2f = ((m2 - m1) * v2 + 2 * m1 * v1) / (m1 + m2);
            
            v1After.textContent = v1f.toFixed(2);
            v2After.textContent = v2f.toFixed(2);
            
            // 计算碰撞后动量和动能
            const p = m1 * v1f + m2 * v2f;
            const k = 0.5 * m1 * v1f * v1f + 0.5 * m2 * v2f * v2f;
            
            pAfter.textContent = p.toFixed(2);
            kAfter.textContent = k.toFixed(2);
            
            return { v1f, v2f };
        }

        // 动画函数
        function animateCollision() {
            const { v1f, v2f } = calculateCollision();
            
            // 重置位置
            ball1.style.left = '100px';
            ball2.style.left = '400px';
            
            // 获取初始速度
            const v1 = parseFloat(v1Slider.value);
            const v2 = parseFloat(v2Slider.value);
            
            // 动画参数
            let pos1 = 100;
            let pos2 = 400;
            let collisionHappened = false;
            const animationSpeed = 0.5;
            
            function animate() {
                // 移动小球1
                if (!collisionHappened && pos1 + 25 >= pos2 - 25) {
                    // 碰撞发生
                    collisionHappened = true;
                    pos1 += v1f * animationSpeed;
                    pos2 += v2f * animationSpeed;
                } else if (!collisionHappened) {
                    // 碰撞前
                    pos1 += v1 * animationSpeed;
                    pos2 += v2 * animationSpeed;
                } else {
                    // 碰撞后
                    pos1 += v1f * animationSpeed;
                    pos2 += v2f * animationSpeed;
                }
                
                ball1.style.left = pos1 + 'px';
                ball2.style.left = pos2 + 'px';
                
                // 检查是否超出边界
                if (pos1 < -50 || pos1 > 850 || pos2 < -50 || pos2 > 850) {
                    return;
                }
                
                requestAnimationFrame(animate);
            }
            
            animate();
        }

        // 事件监听
        m1Slider.addEventListener('input', updateDisplayValues);
        m2Slider.addEventListener('input', updateDisplayValues);
        v1Slider.addEventListener('input', updateDisplayValues);
        v2Slider.addEventListener('input', updateDisplayValues);
        
        startBtn.addEventListener('click', animateCollision);
        
        resetBtn.addEventListener('click', function() {
            // 重置滑块
            m1Slider.value = 2;
            m2Slider.value = 1;
            v1Slider.value = 3;
            v2Slider.value = 0;
            
            // 重置显示
            updateDisplayValues();
            
            // 重置结果
            v1After.textContent = '-';
            v2After.textContent = '-';
            pAfter.textContent = '-';
            kAfter.textContent = '-';
            
            // 重置小球位置
            ball1.style.left = '100px';
            ball2.style.left = '400px';
        });

        // 初始化
        updateDisplayValues();
    </script>
</body>
</html>
        
编辑器加载中
预览
控制台