Previous page : Grouping the particles
Next page : All the code together
As time ticks on the particles move. For the motion in the horizontal direction, we don’t have any force acting, so we basically will do
If we hit a wall, i.e. if the x-coordinate of the centre is closer to a wall than the radius of the particle, we will change the direction of the motion, and undo the last step. We will only change the direction if the particle is moving towards the wall. The reason for this is that if the particle is hit by another particle at the same time as it hits the wall it might be pushed so far into the wall that the undoing step will not move the particle’s edge out of the wall. If the direction of motion is changed now the particle will be stuck in the wall since the direction of the motion will just flip back and forth.
For the motion in the vertical direction, we need to change the velocity too. We get
But the average speed will be
We will use this to update the position in the vertical direction, and then we will update the velocity. In this way, the combined kinetic and potential energy will remain the same.
As with the vertical motion, the direction of the velocity is changed if the particle collides with a horizontal wall, and the last change of position is undone.
The scaling of the speeds and the accelerations is such that Δt can be set to one. That will simplify the calculations greatly.
Here is a bit of JavaScript using this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
// This function moves the particles // and checks if a particle will bounce on a // wall. If so it will change the direction // of the perpendicular component of the // motion. If the particle moves in the vertical // direction the velocity will change due to // gravity. // As the particle moves say downward, it will change // its velocity by gdt, but the average velocity will be // (vOld+vNew)/2=(vOld+vOld+gdt)/2=vOld+gdt/2. // This can be seen in hte code in a few places. function move() { for (let i = 0; i < n; i++) { particles[i].x += particles[i].vx; particles[i].y += particles[i].vy + gDt / 2; if (particles[i].y < radius) { if (particles[i].vy < 0) particles[i].vy *= -1; particles[i].y += particles[i].vy - gDt / 2; } else if (particles[i].y > canvas.height - radius) { if (particles[i].vy > 0) particles[i].vy *= -1; particles[i].y += particles[i].vy - gDt / 2; } else particles[i].vy += gDt; if (particles[i].x < radius) { if (particles[i].vx < 0) particles[i].vx *= -1; particles[i].x += particles[i].vx; } else if (particles[i].x > canvas.width - radius) { if (particles[i].vx > 0) particles[i].vx *= -1; particles[i].x += particles[i].vx; } } } |
Previous page : Grouping the particles
Next page : All the code togetherLast modified: