Processing math: 100%

Ballistic Motion

Ballistic motion is motion that is affected by gravity. Imagine a ball thrown up into the air that rises to its maximum height and then comes back down. For simplicity, we'll ignore winds and friction with the air.
To write a program that simulates ballistic motion, we'll start with the simple, vector motion of a ball model.
Notes Code and Results

Motion without gravity.

We have a ball moving upward (in the y-direction) at 5 m/s, so its velocity vector is: v=<0,5,0>
Notice that:
  • Line 1:
    scene.range = 10
    Sets a constant field of view so we don't automatically zoom in or out as the ball moves.
The core of the model are lines 24 and 25:
ball.pos.x = ball.pos.x + ball.v.x * dt
These equations for the position comes from the fact that, as we all know, velocity is the change in distance over time. Considering only motion in the x direction (vx): vx=ΔxΔt We can write the change in distance (Δx) as the difference in the old and new positions: vx=xnewxoldΔt Therefore, if we know the velocity (v), the time step (Δt), and the starting position (xold), then we can solve this equation to find the new position (xnew). xnew=xold+vxΔt This could be read as: the new position is equal to the old position plus the change in position.

There is no motion in the x direction, but the same general equation applies in y, so:

ball.pos.y = ball.pos.y + ball.v.y * dt
scene.range = 10

ball = sphere(radius=0.5)

ball.v = vector(0, 5, 0)

ball.arrow = arrow(pos = ball.pos, axis = ball.v, shaftwidth=0.2)
ball.vx_arrow = arrow(pos = ball.pos,
                      axis = vec(ball.v.x, 0, 0),
                      color=color.red,
                      shaftwidth=0.2)
ball.vy_arrow = arrow(pos = ball.pos + ball.vx_arrow.axis,
                      axis = vec(0, ball.v.y, 0),
                      color=color.yellow,
                      shaftwidth=0.2)

dt = 0.05

while True:
    sleep(dt)
    sleep(1)

    # update ball position based on velocity vector
    ball.pos.x = ball.pos.x + ball.v.x * dt
    ball.pos.y = ball.pos.y + ball.v.y * dt

    #update positions of the arrows
    ball.arrow.pos = ball.pos
    ball.vx_arrow.pos = ball.pos
    ball.vy_arrow.pos = ball.pos + ball.vx_arrow.axis
    # update directions of arrows
    ball.arrow.axis = ball.v
    ball.vx_arrow.axis = vec(ball.v.x, 0, 0)
    ball.vy_arrow.axis = vec(0, ball.v.y, 0)
The result should look like:
result

Adding gravity (acceleration)

Acceleration is the change in velocity (Δv) with time (Δt) so: a=vnewvoldΔt So for each timestep, we'll solve this equation for the new velocity (vnew ): vnew=vold+aΔt The acceleration due to gravity (g) is: a=g=9.8m/s2 So, for vertical, ballistic motion we can write the equation as: vnew=vold+gΔt We can add this as a single line to the previous program, before we calculate the new position.
  • Line 23:
    ball.v.y = ball.v.y - 9.8 * dt
scene.range = 10

ball = sphere(radius=0.5)

ball.v = vector(0, 10, 0)

ball.arrow = arrow(pos = ball.pos, axis = ball.v, shaftwidth=0.2)
ball.vx_arrow = arrow(pos = ball.pos,
                      axis = vec(ball.v.x, 0, 0),
                      color=color.red,
                      shaftwidth=0.2)
ball.vy_arrow = arrow(pos = ball.pos + ball.vx_arrow.axis,
                      axis = vec(0, ball.v.y, 0),
                      color=color.yellow,
                      shaftwidth=0.2)

dt = 0.05

while True:
    sleep(dt)
    #sleep(1)

    # update velocity based on gravitational acceleration
    ball.v.y = ball.v.y - 9.8 * dt

    # update ball position based on velocity vector
    ball.pos.x = ball.pos.x + ball.v.x * dt
    ball.pos.y = ball.pos.y + ball.v.y * dt

    #update positions of the arrows
    ball.arrow.pos = ball.pos
    ball.vx_arrow.pos = ball.pos
    ball.vy_arrow.pos = ball.pos + ball.vx_arrow.axis
    # update directions of arrows
    ball.arrow.axis = ball.v
    ball.vx_arrow.axis = vec(ball.v.x, 0, 0)
    ball.vy_arrow.axis = vec(0, ball.v.y, 0)

Add a floor

Add a floor to your model so the ball bounces.
result