简介:本文将介绍如何使用JavaScript实现多小球非对心弹性碰撞的模拟。通过理解碰撞的物理原理,我们可以创建出一个有趣且交互性强的可视化效果。
在JavaScript中实现多小球非对心弹性碰撞需要使用到物理原理和数学计算。下面是一个简单的实现步骤:
下面是一个简单的代码示例:
```javascript
const canvas = document.getElementById(‘canvas’);
const ctx = canvas.getContext(‘2d’);
const balls = []; // 存储所有小球
const ballRadius = 20; // 小球半径
const ballColor = ‘blue’; // 小球颜色
const canvasWidth = canvas.width;
const canvasHeight = canvas.height;
// 创建一个小球
function createBall(x, y) {
return {
x, y, vx: 0, vy: 0, radius: ballRadius, color: ballColor,
};
}
// 更新小球的位置
function updateBall(ball) {
ball.x += ball.vx;
ball.y += ball.vy;
}
// 绘制小球
function drawBall(ball) {
ctx.beginPath();
ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2);
ctx.fillStyle = ball.color;
ctx.fill();
}
// 检查两个球是否碰撞
function checkCollision(ball1, ball2) {
const dx = ball1.x - ball2.x;
const dy = ball1.y - ball2.y;
const distance = Math.sqrt(dx dx + dy dy);
return distance < ball1.radius + ball2.radius;
}
// 处理碰撞效果
function handleCollision(ball1, ball2) {
// 这里简单起见,只处理弹性系数为1的情况,也就是完全弹性碰撞
const normalX = (ball2.x - ball1.x) / (ball2.x - ball1.x); // 这里应该是矢量除法,但这里简化为标量除法了
const normalY = (ball2.y - ball1.y) / (ball2.y - ball1.y); // 同上
const collisionAngle = Math.atan2(normalY, normalX); // 碰撞点的法线角度,用于角动量守恒计算
const relativeVelocity = Math.sqrt(ball1.vx ball1.vx + ball1.vy ball1.vy); // 相对速度大小,用于能量守恒计算
const postCollisionVelocity = relativeVelocity / 2; // 假设完全弹性碰撞,速度减半
const postCollisionAngle = collisionAngle - Math.PI / 2; // 根据角动量守恒,改变方向使速度反向,同时角度调整90度以匹配方向改变
ball1.vx = postCollisionVelocity Math.cos(postCollisionAngle); // 应用新的速度分量到第一个球上,注意方向改变后的修正
ball1.vy = postCollisionVelocity Math.sin(postCollisionAngle); // 同上
}
// 主循环,不断更新所有小球的位置和检测碰撞
function mainLoop() {
ctx.clearRect(0, 0, canvasWidth, canvasHeight); // 清空画布,准备重新绘制所有小球的新位置
for (let i = 0; i < balls.length; i++) { // 遍历所有小球,更新位置和绘制新的位置,同时检查是否与其他小球发生碰撞并处理碰撞效果
updateBall(balls[i]); // 更新位置和速度分量(未改变)
drawBall(balls[i]); // 在当前位置绘制小球(未改变)