Monocurl Essays
Series Download

Projectile motion: dropped and fired bullets land together

Gravity acts only on the vertical part of a projectile's motion. From that come the parabola, the time of flight, the range, and why 45 degrees goes farthest.

20 min·High school·

AssumesPosition, velocity and acceleration: reading motion graphsNewton's second law, F = ma: what force really does

Two balls leave a ledge 4.9 m high at the same instant, shown at half speed: one is dropped and one is fired sideways at 6 m/s. A ring marks each ball every tenth of a second, and the rings stay level with each other all the way down.
Monocurl source
let fh = Frame(-1, 6.5, 0, 5.2, [-0.75, 0.15, 0], 4.5, 3.12)
let H0 = 4.9
let V0 = 6
mesh plot = Panel(fh, [0, 1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5], "distance from the ledge (m)", "height (m)")
mesh ledge = Shape([at(fh, -1, 0), at(fh, -0.2, 0), at(fh, -0.2, H0 - 0.15), at(fh, -1, H0 - 0.15)], SLATE, 0.25, 2)
mesh words = [
    center{[2.75, 1.7, 0]} Cap("dropped", 0.76, AZURE),
    center{[2.75, 1.3, 0]} Cap("fired at 6 m/s", 0.76, EMBER),
    center{[2.75, 0.5, 0]} Note("time (s)", 0.74),
    center{[2.75, -0.7, 0]} Note("each has fallen (m)", 0.74)
]
let Fall = |t| block {
    for (k in range(0, to_int(floor(t / 0.1 + 0.001)) + 1)) {
        let u = 0.1 * k
        let y = H0 - 0.5 * G * u * u
        if (mod(k, 2) == 0 and k > 0 and k < 10) {
            . Seg(at(fh, 0, y), at(fh, V0 * u, y), SLATE, 1.5)
        }
        . Ring(at(fh, 0, y), AZURE, 0.065, 2.5)
        . Ring(at(fh, V0 * u, y), EMBER, 0.065, 2.5)
    }
    . Pt(at(fh, 0, H0 - 0.5 * G * t * t), AZURE, 0.1)
    . Pt(at(fh, V0 * t, H0 - 0.5 * G * t * t), EMBER, 0.1)
    . center{[2.75, 0.02, 0]} scale{1.4} color{INK} Number(t, 2)
    . center{[2.75, -1.18, 0]} scale{1.4} color{INK} Number(0.5 * G * t * t, 2)
}
mesh fall = Fall(t: 0)

slide "fall"
    play Wait(0.8)
    fall.t = 1
    play Lerp(2, [&fall], linear)
    play Wait(1.6)

Uses the shared definitions for this lesson's figures.

A rifle is held level, 1.5 m above flat ground, and fired. At the instant the bullet leaves the barrel, a second bullet is dropped from the same height. One of them is moving at 400 m/s and will come down two hundred meters away; the other falls at your feet. Which hits the ground first?

Pause and try

Commit to an answer and a reason before reading on: the dropped bullet, the fired bullet, or neither.

Show answerHide answer

Neither. With air resistance ignored they land at the same instant, about 0.55 s after release. Most people pick the dropped bullet, feeling that the fired one’s speed should hold it up for a while. The animation above runs the same experiment with slower balls, and the rest of the lesson explains why forward speed gives no protection against falling.

What the strobe picture shows

In the animation the two balls leave a ledge 4.9 m high. Read the heights of the rings. After 0.2 s both balls have fallen 0.20 m; after 0.4 s, 0.78 m; after 0.6 s, 1.76 m; after 1.0 s, 4.9 m, and both are on the ground. These are the distances $\tfrac12 g t^2 = 4.9t^2$ that a body dropped from rest falls in $t$ seconds, where $g = 9.8$ m/s² is the acceleration of free fall. The fired ball falls exactly as if it had been dropped.

Now read the fired ball’s horizontal positions: 1.2 m, 2.4 m, 3.6 m, and 6 m at landing. It covers 0.6 m in every tenth of a second, which is a steady 6 m/s, exactly as if gravity were absent.

So the fired ball seems to be doing two simple things at once: moving sideways at constant velocity, and falling like a dropped ball. Neither motion takes any notice of the other. That is a strong claim, and a picture of one experiment does not prove it. Newton’s second law does.

Why the two motions are independent

The second law says that the net force on an object equals its mass times its acceleration, and that this holds separately along each of two perpendicular axes: $\sum F_x = ma_x$ and $\sum F_y = ma_y$. Take $x$ horizontal, in the direction the ball is fired, and $y$ vertically upward.

Once the ball is in the air, and if we neglect air resistance, exactly one force acts on it: its weight, of magnitude $mg$, straight down. Whatever threw the ball stopped pushing when the ball left it. The weight has no horizontal component, so

$$ 0 = m a_x \quad\text{and}\quad -mg = m a_y, \qquad\text{that is,}\qquad a_x = 0, \quad a_y = -g. $$

Look at what each equation contains. The vertical one says the vertical velocity changes at the rate $-g$, and it mentions neither the horizontal position nor the horizontal velocity. A ball moving sideways at 6 m/s, a bullet moving at 400 m/s and a ball not moving sideways at all obey the same vertical equation, and if they start with the same height and the same vertical velocity (zero), they have the same height at every later moment. The horizontal equation says the horizontal velocity never changes, and it does not mention the vertical motion.

The independence is a consequence of this particular force, and it is worth knowing how it could fail. If the force on the ball had a horizontal part that depended on the vertical motion, the two equations would be tied together. Air resistance does exactly that, as we will see at the end.

A ball kicked at 20 m/s, 60 degrees above the ground, in real time. Its shadow on the ground (blue) moves at a constant 10 m/s; its shadow on the wall (orange) rises and falls like a ball thrown straight up at 17.3 m/s. A dot is left every half second.
Monocurl source
let V0 = 20
let DEG = 60
let TF = flight(V0, DEG)
let fs = Frame(0, 40, 0, 17, [0.2, 0.2, 0], 6.2, 2.635)
mesh plot = Panel(fs, [5, 10, 15, 20, 25, 30, 35, 40], [5, 10, 15], [0, 10, 20, 30, 40], [0, 5, 10, 15], "distance along the ground (m)", "height (m)")
let Shadows = |t| block {
    let x = px(V0, DEG, t)
    let y = max(0, py(V0, DEG, t))
    . Flown(fs, V0, DEG, t, SLATE, 3)
    . Seg(at(fs, x, 0), at(fs, x, y), AZURE, 1.5)
    . Seg(at(fs, 0, y), at(fs, x, y), EMBER, 1.5)
    for (k in range(0, to_int(floor(t / 0.5 + 0.001)) + 1)) {
        . Pt(at(fs, px(V0, DEG, 0.5 * k), 0), AZURE, 0.06)
        . Pt(at(fs, 0, py(V0, DEG, 0.5 * k)), EMBER, 0.06)
    }
    . Pt(at(fs, x, 0), AZURE, 0.1)
    . Pt(at(fs, 0, y), EMBER, 0.1)
    . Pt(at(fs, x, y), INK, 0.11)
}
mesh shadows = Shadows(t: 0)

slide "kick"
    play Wait(0.8)
    shadows.t = TF
    play Lerp(TF, [&shadows], linear)
    play Wait(1.6)

Uses the shared definitions for this lesson's figures.

The equations of a projectile

To use the idea we need the two one-dimensional motions as formulas. Both are motions with constant acceleration, and for those the earlier lesson on motion graphs derived, from the area under a velocity graph, that an object starting at position $x_0$ with velocity $v_0$ and constant acceleration $a$ has

$$ v = v_0 + at, \qquad x = x_0 + v_0 t + \tfrac12 a t^2. $$

We also need the starting velocity along each axis. A launch at speed $v_0$ and angle $\theta$ above the horizontal is an arrow of length $v_0$ tilted at $\theta$. It is the hypotenuse of a right triangle whose horizontal side is $v_0\cos\theta$ and whose vertical side is $v_0\sin\theta$; those two sides are the horizontal and vertical components of the launch velocity.

The fired ball of the opening is the case $\theta = 0$, launched from height 4.9 m: $x = 6t$ and the height is $4.9 - 4.9t^2$, which is zero at $t = 1$ s whatever the 6 is replaced by.

Here is a more typical case, the one in the last animation: a ball kicked from the ground at $v_0 = 20$ m/s and $\theta = 60°$. Its velocity components at launch are $20\cos 60° = 10$ m/s and $20\sin 60° = 17.3$ m/s. The vertical motion decides how long it stays up. It rises until $v_y = 0$, which happens when $17.3 - 9.8t = 0$, at $t = 1.77$ s, and by then it has climbed to $y = 17.3(1.77) - 4.9(1.77)^2 = 15.3$ m. It returns to the ground when $y = 0$ again: $t\,(17.3 - 4.9t) = 0$ gives $t = 3.53$ s, twice the time to the top. All that while it has been moving sideways at 10 m/s, so it lands $10 \times 3.53 = 35.3$ m away.

Pause and try

Repeat the calculation for the same kick speed at a lower angle: $v_0 = 20$ m/s and $\theta = 30°$. Find the time of flight, the greatest height and the landing distance. Compare the landing distance with the $60°$ kick.

Show answerHide answer

The components swap: $v_x = 20\cos 30° = 17.3$ m/s and $v_y = 20\sin 30° = 10$ m/s at launch. Top of the flight: $10 - 9.8t = 0$, so $t = 1.02$ s, at height $10(1.02) - 4.9(1.02)^2 = 5.1$ m. Landing: $t = 2.04$ s, at $x = 17.3 \times 2.04 = 35.3$ m. The low kick is in the air for less time and rises a third as high, and it lands in the same place as the high one. The reason comes out of the general formulas below.

The path is a parabola

There is a second way to read the equation $y = (v_0\sin\theta)t - \tfrac12 gt^2$, and it makes the shape of the path visible. The first term alone is where the ball would be if gravity were switched off: moving along its line of aim at a steady $v_0$. The second term is the distance a dropped ball falls in the same time.

  1. With gravity switched off the ball would follow its line of aim at a steady 20 m/s, covering 10 m every half second.
  2. Gravity puts it below that line by the distance a dropped ball falls in the same time: 1.2 m, 4.9 m, 11.0 m and 19.6 m.
  3. The actual positions lie on one smooth curve, the path of the ball. It lands just after 2 s.
The 30 degree kick at 20 m/s. Without gravity the ball would move along its line of aim; with gravity it is below that line by the distance a dropped ball falls in the same time.
Monocurl source
let V0 = 20
let DEG = 30
let fl = Frame(0, 38, 0, 22, [-0.65, 0.2, 0], 4.9, 2.837)
let TS = [0.5, 1, 1.5, 2]
let aim = |t| at(fl, px(V0, DEG, t), V0 * sin(deg_to_rad(DEG)) * t)
let real = |t| at(fl, px(V0, DEG, t), py(V0, DEG, t))
mesh plot = Panel(fl, [10, 20, 30], [5, 10, 15, 20], [0, 10, 20, 30], [0, 5, 10, 15, 20], "distance along the ground (m)", "height (m)")
mesh line = []
mesh drops = []
mesh curve = []
mesh rows = []

slide "With gravity switched off the ball would follow its line of aim at a steady 20 m/s, covering 10 m every half second."
    line = [
        dashed{[0.14, 0.09]} stroke{SLATE, 3} Line(aim(0), aim(2.15)),
        map(TS, |t| Ring(aim(t), SLATE, 0.075, 2.5))
    ]
    play Fade(0.8, [&line])

slide "Gravity puts it below that line by the distance a dropped ball falls in the same time: 1.2 m, 4.9 m, 11.0 m and 19.6 m."
    drops = map(TS, |t| [Seg(aim(t) - [0, 0.09, 0], real(t), EMBER, 4), Pt(real(t), AZURE, 0.09)])
    rows = block {
        . center{[2.85, 1.75, 0]} Note("fallen below", 0.74)
        . center{[2.85, 1.42, 0]} Note("the aim line", 0.74)
        for (i in range(0, 4)) {
            . center{[2.85, 0.85 - 0.5 * i, 0]} Math(str_join([to_string(TS[i], 1), "\text{ s}:\ \ ", to_string(0.5 * G * TS[i] * TS[i], 1), "\text{ m}"]), 0.82, EMBER)
        }
    }
    play Fade(0.8, [&drops, &rows])

slide "The actual positions lie on one smooth curve, the path of the ball. It lands just after 2 s."
    curve = Flown(fl, V0, DEG, flight(V0, DEG), AZURE, 4)
    play Write(1.4, [&curve])

Uses the shared definitions for this lesson's figures.

To get the curve as an equation in $x$ and $y$ alone, eliminate the clock. From the horizontal motion $t = x/(v_0\cos\theta)$, which is allowed when $\cos\theta \neq 0$, that is, when the launch is not straight up. Substituting into $y$:

$$ y = (v_0\sin\theta)\frac{x}{v_0\cos\theta} - \frac{g}{2}\left(\frac{x}{v_0\cos\theta}\right)^2 = x\tan\theta - \frac{g}{2v_0^2\cos^2\theta}\,x^2. $$

This has the form $y = bx - cx^2$ with $c > 0$, the equation of a parabola opening downward. The first term, $x\tan\theta$, is the line of aim, and the second is the fall below it.

The 60 degree kick at four moments a quarter of the flight apart. The horizontal part of the velocity (blue) is the same every time; the vertical part (orange) shrinks, vanishes at the top and reverses.
The 60 degree kick at four moments a quarter of the flight apart. The horizontal part of the velocity (blue) is the same every time; the vertical part (orange) shrinks, vanishes at the top and reverses.
Monocurl source
let V0 = 20
let DEG = 60
let TF = flight(V0, DEG)
let S = 0.05
let fv = Frame(0, 38, 0, 18, [-0.65, 0.2, 0], 4.9, 2.321)
let TS = [0, TF / 4, TF / 2, 3 * TF / 4]
let vx = V0 * cos(deg_to_rad(DEG))
let vy = |t| V0 * sin(deg_to_rad(DEG)) - G * t
mesh plot = Panel(fv, [10, 20, 30], [5, 10, 15], [0, 10, 20, 30], [0, 5, 10, 15], "distance along the ground (m)", "height (m)")
mesh path = Flown(fv, V0, DEG, TF, SLATE, 3)
mesh arrows = block {
    for (t in TS) {
        let p = at(fv, px(V0, DEG, t), py(V0, DEG, t))
        . Arrow2(p, [S * vx, 0, 0], AZURE)
        if (abs(vy(t)) > 1) {
            . Arrow2(p, [0, S * vy(t), 0], EMBER)
        }
        . Pt(p, INK, 0.09)
    }
}
mesh rows = block {
    . center{[2.85, 1.8, 0]} Cap("vertical velocity", 0.74, EMBER)
    for (i in range(0, 4)) {
        . center{[2.85, 1.3 - 0.47 * i, 0]} Math(str_join([to_string(TS[i], 2), "\text{ s}:\ \ ", to_string(abs(vy(TS[i])) * sign(to_int(vy(TS[i]) * 100)), 1), "\text{ m/s}"]), 0.8, EMBER)
    }
    . center{[2.85, -0.9, 0]} Cap("horizontal velocity", 0.74, AZURE)
    . center{[2.85, -1.38, 0]} Math(str_join([to_string(vx, 1), "\text{ m/s always}"]), 0.8, AZURE)
}

Uses the shared definitions for this lesson's figures.

Time of flight, height and range

The two worked kicks followed the same three steps, so we can run those steps once with letters. The results hold for a projectile that lands at the height it was launched from.

Since $2\sin\theta\cos\theta = \sin 2\theta$ (the double-angle identity), the range is often written $R = v_0^2\sin 2\theta/g$. A units check: $v_0^2/g$ is (m²/s²)/(m/s²) = m, and the trigonometric factors are pure numbers, so $R$ and $H$ are lengths; $v_0/g$ is (m/s)/(m/s²) = s, so $T$ is a time.

The proof of part 4 also says why $60°$ and $30°$ tied. Range is horizontal speed times time aloft, and time aloft is proportional to vertical launch speed. The $60°$ kick has vertical speed 17.3 and horizontal speed 10; the $30°$ kick has them the other way round. The product is the same. At $45°$ the two components are equal, and a product of two numbers whose squares have a fixed sum is largest when the numbers are equal.

Pause and try

A ball is kicked at 20 m/s at angles of $15°$, $30°$, $45°$, $60°$ and $75°$. Before watching the next animation, rank the five landing distances, and say which kick is in the air longest.

Show answerHide answer

$45°$ lands farthest, at $20^2/9.8 = 40.8$ m. $30°$ and $60°$ tie at 35.3 m, and $15°$ and $75°$ tie at $40.8 \times \sin 30° = 20.4$ m. The $75°$ kick is in the air longest, 3.94 s, because time of flight depends only on the vertical launch speed.

Five balls kicked together at 20 m/s, at angles from 15 to 75 degrees, in real time. The 45 degree ball lands farthest, and the pairs 30 and 60 degrees, 15 and 75 degrees, come down at the same points at different times.
Monocurl source
let V0 = 20
let ff = Frame(0, 42, 0, 20, [-0.6, 0.2, 0], 5.5, 2.62)
let SHOTS = [[75, EMBER], [60, AZURE], [45, LEAF], [30, AZURE], [15, EMBER]]
mesh plot = Panel(ff, [10, 20, 30, 40], [5, 10, 15, 20], [0, 10, 20, 30, 40], [0, 5, 10, 15, 20], "distance along the ground (m)", "height (m)")
mesh legend = block {
    . center{[3.05, 1.75, 0]} Note("angle, range", 0.74)
    for (i in range(0, 5)) {
        let sh = SHOTS[i]
        . center{[3.05, 1.2 - 0.52 * i, 0]} Cap(str_join([to_string(sh[0]), "°   ", to_string(px(V0, sh[0], flight(V0, sh[0])), 1), " m"]), 0.78, sh[1])
    }
}
let Fan = |t| block {
    for (sh in SHOTS) {
        let u = min(t, flight(V0, sh[0]))
        . Flown(ff, V0, sh[0], u, sh[1], 3.5)
        . Pt(at(ff, px(V0, sh[0], u), max(0, py(V0, sh[0], u))), sh[1], 0.09)
    }
}
mesh fan = Fan(t: 0)

slide "fan"
    play Wait(0.8)
    fan.t = 4
    play Lerp(4, [&fan], linear)
    play Wait(1.6)

Uses the shared definitions for this lesson's figures.

Range against launch angle for a launch speed of 20 m/s on level ground. The curve is symmetric about 45 degrees, where it peaks at 40.8 m; angles equally far from 45 degrees on either side give the same range.
Range against launch angle for a launch speed of 20 m/s on level ground. The curve is symmetric about 45 degrees, where it peaks at 40.8 m; angles equally far from 45 degrees on either side give the same range.
Monocurl source
let V0 = 20
let range_at = |deg| V0 * V0 * sin(deg_to_rad(2 * deg)) / G
let fr = Frame(0, 90, 0, 45, [0.15, 0.2, 0], 6.2, 2.9)
mesh plot = Panel(fr, [15, 30, 45, 60, 75, 90], [10, 20, 30, 40], [0, 15, 30, 45, 60, 75, 90], [0, 10, 20, 30, 40], "launch angle (degrees)", "range R (m)")
mesh pairs = [
    dashed{[0.12, 0.08]} stroke{AZURE, 2.5} Line(at(fr, 30, range_at(30)), at(fr, 60, range_at(60))),
    dashed{[0.12, 0.08]} stroke{EMBER, 2.5} Line(at(fr, 15, range_at(15)), at(fr, 75, range_at(75))),
    dashed{[0.12, 0.08]} stroke{LEAF, 2.5} Line(at(fr, 45, 0), at(fr, 45, range_at(45)))
]
mesh curve = Graph(fr, range_at, 0, 90, SLATE, 4)
mesh dots = [
    Pt(at(fr, 15, range_at(15)), EMBER, 0.1), Pt(at(fr, 75, range_at(75)), EMBER, 0.1),
    Pt(at(fr, 30, range_at(30)), AZURE, 0.1), Pt(at(fr, 60, range_at(60)), AZURE, 0.1),
    Pt(at(fr, 45, range_at(45)), LEAF, 0.11)
]

Uses the shared definitions for this lesson's figures.

Worked examples

The stone thrown from the 20 m cliff at 15 m/s and 40 degrees, in real time. Its speed drops to 11.5 m/s at the top of the path, where only the horizontal velocity is left, and reaches 24.8 m/s at the water.
Monocurl source
let V0 = 15
let DEG = 40
let HC = 20
let VY = V0 * sin(deg_to_rad(DEG))
let TL = (VY + sqrt(VY * VY + 2 * G * HC)) / G
let fc = Frame(-4, 40, 0, 26, [-0.5, 0.15, 0], 5.2, 3.07)
mesh plot = Panel(fc, [0, 10, 20, 30, 40], [5, 10, 15, 20, 25], [0, 10, 20, 30, 40], [0, 5, 10, 15, 20, 25], "distance from the cliff (m)", "height above the sea (m)")
mesh cliff = Shape([at(fc, -4, 0), at(fc, 0, 0), at(fc, 0, HC), at(fc, -4, HC)], SLATE, 0.25, 2)
mesh words = [
    center{[2.95, 1.2, 0]} Note("time (s)", 0.74),
    center{[2.95, -0.2, 0]} Note("speed (m/s)", 0.74)
]
let Throw = |t| {
    let n = to_int(max(2, ceil(t * 24)))
    let vy = VY - G * t
    let vx = V0 * cos(deg_to_rad(DEG))
    return [
        stroke{AZURE, 4} Polyline(map(sample(0, max(t, 0.02), n), |u| at(fc, px(V0, DEG, u), HC + py(V0, DEG, u)))),
        Pt(at(fc, px(V0, DEG, t), max(0, HC + py(V0, DEG, t))), EMBER, 0.1),
        center{[2.95, 0.72, 0]} scale{1.4} color{INK} Number(t, 2),
        center{[2.95, -0.68, 0]} scale{1.4} color{EMBER} Number(sqrt(vx * vx + vy * vy), 1)
    ]
}
mesh throw = Throw(t: 0)

slide "throw"
    play Wait(0.8)
    throw.t = TL
    play Lerp(TL, [&throw], linear)
    play Wait(1.6)

Uses the shared definitions for this lesson's figures.

What air resistance changes

Every result above assumed that gravity is the only force. For a shot put, or a ball tossed across a room, that is accurate to a percent or so. For a fast, light object it is not. Air resistance is a force directed against the velocity, and for a ball at sporting speeds its size grows roughly as the square of the speed.

A baseball hit at 45 m/s and 45 degrees: the parabola it would follow with no air, and a path computed with air resistance proportional to the square of the speed, for a ball whose terminal speed is 40 m/s. The table above the plot gives the range and the peak height of each path, and a dot marks each peak.
A baseball hit at 45 m/s and 45 degrees: the parabola it would follow with no air, and a path computed with air resistance proportional to the square of the speed, for a ball whose terminal speed is 40 m/s. The table above the plot gives the range and the peak height of each path, and a dot marks each peak.
Monocurl source
let V0 = 45
let DEG = 45
let VT = 40
let DT = 0.005
let fd = Frame(0, 210, 0, 55, [0.2, -0.45, 0], 6.9, 1.807)
# step the motion forward with drag acceleration (g / vt^2) * speed * velocity
let Dragged = |every| {
    let k = G / (VT * VT)
    var x = 0
    var y = 0
    var vx = V0 * cos(deg_to_rad(DEG))
    var vy = V0 * sin(deg_to_rad(DEG))
    var pts = [[0, 0]]
    var i = 0
    while (y >= 0) {
        let v = sqrt(vx * vx + vy * vy)
        vx = vx - k * v * vx * DT
        vy = vy - (G + k * v * vy) * DT
        x = x + vx * DT
        y = y + vy * DT
        i = i + 1
        if (mod(i, every) == 0 and y > 0) {
            pts .= [x, y]
        }
    }
    pts .= [x, 0]
    return pts
}
let PTS = Dragged(12)
let REACH = PTS[len(PTS) - 1][0]
mesh plot = Panel(fd, [50, 100, 150, 200], [25, 50], [0, 50, 100, 150, 200], [0, 25, 50], "distance along the ground (m)", "height (m)")
mesh vacuum = Flown(fd, V0, DEG, flight(V0, DEG), AZURE, 4)
mesh air = stroke{EMBER, 4} Polyline(map(PTS, |p| at(fd, p[0], p[1])))
let TOP_T = flight(V0, DEG) / 2
let PEAK = reduce(PTS, PTS[0], |best, p| [best, p][to_int(p[1] > best[1])])
let metres = |v| str_join([to_string(v, 0), "\text{ m}"])
mesh peaks = [
    Pt(at(fd, px(V0, DEG, TOP_T), py(V0, DEG, TOP_T)), AZURE, 0.085),
    Pt(at(fd, PEAK[0], PEAK[1]), EMBER, 0.085)
]
mesh words = [
    center{[1.0, 1.93, 0]} Note("range", 0.74),
    center{[2.6, 1.95, 0]} Note("peak height", 0.74),
    Seg([-3.4, 1.56, 0], [-2.95, 1.56, 0], AZURE, 4),
    center{[-2.47, 1.56, 0]} Cap("no air", 0.78, AZURE),
    center{[1.0, 1.56, 0]} Math(metres(px(V0, DEG, flight(V0, DEG))), 0.85, AZURE),
    center{[2.6, 1.56, 0]} Math(metres(py(V0, DEG, TOP_T)), 0.85, AZURE),
    Seg([-3.4, 1.16, 0], [-2.95, 1.16, 0], EMBER, 4),
    center{[-1.95, 1.16, 0]} Cap("with air resistance", 0.78, EMBER),
    center{[1.0, 1.16, 0]} Math(metres(REACH), 0.85, EMBER),
    center{[2.6, 1.16, 0]} Math(metres(PEAK[1]), 0.85, EMBER)
]

Uses the shared definitions for this lesson's figures.

Four things change, and each can be read off the figure or the force.

  1. The range and the height shrink. In this model the baseball’s range drops from 207 m to about 111 m. Real fly balls hit this hard travel about 120 m.
  2. The path is no longer symmetric. The ball loses horizontal velocity all the way along, so it comes down more steeply than it went up, and the highest point is past the middle of the range.
  3. The best angle is below $45°$. A flatter launch spends less time fighting the air. For this model the greatest range is at about $40°$.
  4. The two motions are no longer independent. The drag force points against the velocity and its size depends on the total speed, so the vertical equation now contains the horizontal velocity. A fast horizontal bullet feels a larger vertical drag while it falls than a dropped one does, and it lands slightly later. The dropped and fired bullets land together only in the model without air.

The model has other boundaries. The ground was taken to be flat and $g$ constant; for an artillery shell that travels tens of kilometers, or a rocket, the Earth’s curvature and the weakening of gravity with height both matter. And if the launch and landing heights differ, as in the cliff example, the component equations still hold but the level-ground formulas, and with them the $45°$ rule, do not.

Check yourself

A soccer ball is kicked at an angle and air resistance is negligible. At the highest point of its path, which statement is true?

In the cliff example the landing speed could have been found without the angle at all. The next lesson, on conservation of energy, explains why.

Problems

Use $g = 9.8$ m/s² and neglect air resistance unless a problem says otherwise.

Problem 1

A ball rolls off the edge of a table 1.2 m high at 2.5 m/s. How long is it in the air, and how far from the foot of the table does it land?

Show solutionHide solution

Origin on the floor below the edge, $y$ up, $x$ along the ball’s direction. Vertically the ball starts at 1.2 m with $v_y = 0$: $0 = 1.2 - 4.9t^2$, so $t = \sqrt{1.2/4.9} = 0.495$ s. Horizontally $x = 2.5 \times 0.495 = 1.24$ m.

Problem 2

A ball is kicked from level ground at 18 m/s and $35°$. Find its time of flight, range and greatest height.

Show solutionHide solution

$v_0\sin\theta = 18 \times 0.5736 = 10.32$ m/s and $v_0\cos\theta = 18 \times 0.8192 = 14.74$ m/s. $T = 2(10.32)/9.8 = 2.11$ s. $R = 14.74 \times 2.11 = 31.1$ m (the formula $18^2\sin 70°/9.8$ gives the same). $H = 10.32^2/(2 \times 9.8) = 5.44$ m.

Problem 3

For the kick in the previous problem, find the ball’s speed at the top of its path, and its speed and direction of motion at the instant it lands.

Show solutionHide solution

At the top $v_y = 0$, so the speed is $v_x = 14.74$ m/s. At landing $t = T$, and $v_y = v_0\sin\theta - gT = v_0\sin\theta - 2v_0\sin\theta = -v_0\sin\theta = -10.32$ m/s, while $v_x = 14.74$ m/s. The speed is $\sqrt{14.74^2 + 10.32^2} = 18$ m/s, the launch speed, and the direction is $35°$ below the horizontal. On level ground a projectile lands with its launch speed, at its launch angle mirrored downward.

Problem 4

A stone thrown horizontally from the top of a cliff hits the sea 2.0 s later, 24 m from the base of the cliff. Find the speed of the throw, the height of the cliff, and the stone’s speed and direction at impact.

Show solutionHide solution

Horizontal: $24 = v_0 \times 2.0$, so $v_0 = 12$ m/s. Vertical: the stone falls $\tfrac12(9.8)(2.0)^2 = 19.6$ m, the height of the cliff. At impact $v_x = 12$ m/s and $v_y = -9.8 \times 2.0 = -19.6$ m/s, so the speed is $\sqrt{12^2 + 19.6^2} = 23.0$ m/s, directed at $\tan^{-1}(19.6/12) = 58.5°$ below the horizontal.

Problem 5

Show that for a projectile on level ground, $H/R = \tfrac14\tan\theta$. What is the greatest height of a $45°$ launch as a fraction of its range? At what launch angle does a projectile rise exactly as high as it travels?

Show solutionHide solution

$\dfrac{H}{R} = \dfrac{v_0^2\sin^2\theta}{2g} \cdot \dfrac{g}{2v_0^2\sin\theta\cos\theta} = \dfrac{\sin\theta}{4\cos\theta} = \tfrac14\tan\theta$. At $45°$, $\tan\theta = 1$ and $H = R/4$: the 20 m/s kick at $45°$ has $R = 40.8$ m and $H = 10.2$ m. $H = R$ requires $\tan\theta = 4$, that is, $\theta = 76.0°$. The speed and $g$ cancel, so these statements hold for any launch speed, on any planet.

Problem 6

A zookeeper aims a tranquilizer dart straight at a monkey hanging from a branch. At the instant the dart is fired, the monkey lets go and drops. Show that the dart hits the monkey whatever the dart’s speed, provided the dart reaches the monkey’s vertical line before either hits the ground.

Show solutionHide solution

Use the “line of aim minus a free fall” description. Let $P$ be the monkey’s starting point. With gravity off, the dart would travel along the straight line of aim and reach $P$ at some time $t^*$ (equal to the horizontal distance to the monkey divided by $v_0\cos\theta$). With gravity on, the dart at time $t^*$ is below $P$ by $\tfrac12 g t^{*2}$, directly under it, since gravity does not change the horizontal motion. The monkey started at $P$ at rest and has been falling for the same time $t^*$, so it is also $\tfrac12 g t^{*2}$ below $P$. Dart and monkey are at the same point at the same time. A faster dart only makes $t^*$ smaller, so they meet higher up; the argument fails only if $\tfrac12 g t^{*2}$ exceeds the monkey’s starting height, in which case both reach the ground first.

Problem 7

A stone is thrown at speed $v_0$ from a height $h$ above level ground. (a) Prove that its speed when it reaches the ground is $\sqrt{v_0^2 + 2gh}$, whatever the launch angle. (b) Check this against the cliff example in the lesson.

Show solutionHide solution

(a) Let the launch angle be $\theta$ (positive, zero or negative). The horizontal velocity stays $v_x = v_0\cos\theta$. The vertical motion has constant acceleration $-g$ and vertical displacement $-h$, and for constant acceleration $v^2 = v_{\text{start}}^2 + 2a\,\Delta y$, so $v_y^2 = v_0^2\sin^2\theta + 2gh$. The landing speed satisfies

$$ v^2 = v_x^2 + v_y^2 = v_0^2\cos^2\theta + v_0^2\sin^2\theta + 2gh = v_0^2 + 2gh, $$

using $\sin^2\theta + \cos^2\theta = 1$. The angle has dropped out. (b) $\sqrt{15^2 + 2(9.8)(20)} = \sqrt{617} = 24.8$ m/s, as found there.

Problem 8

From the 20 m cliff of the lesson, with the same throwing speed of 15 m/s, compare the horizontal distances reached by throws at $45°$ and at $30°$. What does the result say about the $45°$ rule?

Show solutionHide solution

Use $y = 20 + (v_0\sin\theta)t - 4.9t^2 = 0$ for each. At $45°$: both components are $15 \times 0.7071 = 10.61$ m/s. $t = \dfrac{10.61 + \sqrt{10.61^2 + 392}}{9.8} = \dfrac{10.61 + 22.46}{9.8} = 3.37$ s, and $x = 10.61 \times 3.37 = 35.8$ m. At $30°$: $v_{y0} = 7.5$ m/s and $v_x = 12.99$ m/s. $t = \dfrac{7.5 + \sqrt{7.5^2 + 392}}{9.8} = \dfrac{7.5 + 21.17}{9.8} = 2.93$ s, and $x = 12.99 \times 2.93 = 38.0$ m. The $30°$ throw goes farther. When the landing point is below the launch point the stone has extra time in the air however it is thrown, so horizontal speed is worth more than it is on level ground, and the best angle falls below $45°$. Part 4 of the theorem assumed equal launch and landing heights, and that hypothesis cannot be dropped.

Shared definitions used by this lesson's figures
# house kit: prepended to every essay figure after the std imports

# palette. AZURE and EMBER are the two actors, LEAF marks an answer, ROSE a problem
let PAPER = [1, 1, 1, 1]
let INK = [0.08, 0.09, 0.11, 1]
let SLATE = [0.40, 0.44, 0.50, 1]
let MIST = [0.85, 0.86, 0.88, 1]
let AZURE = [0.13, 0.42, 0.68, 1]
let EMBER = [0.89, 0.42, 0.12, 1]
let LEAF = [0.13, 0.55, 0.36, 1]
let ROSE = [0.78, 0.22, 0.24, 1]
let PLUM = [0.47, 0.30, 0.66, 1]
let GOLD = [0.85, 0.62, 0.08, 1]

background = PAPER

# an opaque pastel of col; use for fills so overlaps do not darken
let tint = |col, amount = 0.18| [
    1 - (1 - col[0]) * amount,
    1 - (1 - col[1]) * amount,
    1 - (1 - col[2]) * amount,
    1
]

# text: Cap for labels, Note for quiet labels, Math for typeset maths
let Cap = |txt, size = 0.75, col = INK| color{col} Text(txt, size, "Charter")
let Note = |txt, size = 0.65| color{SLATE} Text(txt, size, "Charter")
let Math = |tex, size = 0.9, col = INK| color{col} Tex(tex, size)

# a paper rectangle to sit behind text that crosses lines
let Plate = |pos, size| center{pos} fill{PAPER} stroke{alpha{0} PAPER, 0} Rect(size)

# shapes with fill and stroke both set, so no stray black appears
let Pt = |pos, col = INK, r = 0.075| center{pos} fill{col} stroke{col, 1} Circle(r, 48)
let Ring = |pos, col = INK, r = 0.1, w = 3| center{pos} fill{PAPER} stroke{col, w} Circle(r, 48)
let Seg = |a, b, col = INK, w = 3| stroke{col, w} Line(a, b)
let Path = |pts, col = INK, w = 3| stroke{col, w} Polyline(pts)
let Region = |pts, col| fill{col} stroke{alpha{0} col, 0} Polygon(pts)
let Outline = |pts, col = INK, w = 3| fill{alpha{0} PAPER} stroke{col, w} Polygon(pts)
let Shape = |pts, col, amount = 0.18, w = 3| fill{tint(col, amount)} stroke{col, w} Polygon(pts)
let Disc = |pos, r, col, amount = 0.18, w = 3| center{pos} fill{tint(col, amount)} stroke{col, w} Circle(r, 96)
let Box = |pos, size, col, amount = 0.18, w = 3| center{pos} fill{tint(col, amount)} stroke{col, w} Rect(size)
# a line from a to b ending in a small solid arrowhead
let Tip = |a, b, col = INK, w = 3, head = 0.17| {
    let d = normalize([b[0] - a[0], b[1] - a[1], 0])
    let n = [-d[1], d[0], 0]
    let base = [b[0] - d[0] * head, b[1] - d[1] * head, 0]
    return [
        stroke{col, w} Line(a, base),
        fill{col} stroke{col, 1} Polygon([
            b,
            [base[0] + n[0] * head * 0.42, base[1] + n[1] * head * 0.42, 0],
            [base[0] - n[0] * head * 0.42, base[1] - n[1] * head * 0.42, 0]
        ])
    ]
}

# plots. a frame is [x0, x1, y0, y1, centre, width, height]: a data window and the scene box it fills
let Frame = |x0, x1, y0, y1, c = [0, 0, 0], w = 6.4, h = 3.6| [x0, x1, y0, y1, c, w, h]
let fx = |fr, x| fr[4][0] + (x - (fr[0] + fr[1]) / 2) * fr[5] / (fr[1] - fr[0])
let fy = |fr, y| fr[4][1] + (y - (fr[2] + fr[3]) / 2) * fr[6] / (fr[3] - fr[2])
let at = |fr, x, y| [fx(fr, x), fy(fr, y), 0]

# axes through the data origin (or the nearest edge of the window), with optional names
let Axes = |fr, x_name = "", y_name = "", col = SLATE| {
    let ox = clamp(fr[0], 0, fr[1])
    let oy = clamp(fr[2], 0, fr[3])
    var parts = [
        Tip(at(fr, fr[0], oy), [fx(fr, fr[1]) + 0.25, fy(fr, oy), 0], col, 2.5, 0.15),
        Tip(at(fr, ox, fr[2]), [fx(fr, ox), fy(fr, fr[3]) + 0.25, 0], col, 2.5, 0.15)
    ]
    if (x_name != "") {
        parts .= center{[fx(fr, fr[1]) + 0.5, fy(fr, oy), 0]} Math(x_name, 0.8, col)
    }
    if (y_name != "") {
        parts .= center{[fx(fr, ox), fy(fr, fr[3]) + 0.5, 0]} Math(y_name, 0.8, col)
    }
    return parts
}

# tick marks with numbers at the listed data values
let XTicks = |fr, xs, col = SLATE, places = 0| block {
    let oy = fy(fr, clamp(fr[2], 0, fr[3]))
    for (x in xs) {
        . Seg([fx(fr, x), oy - 0.07, 0], [fx(fr, x), oy + 0.07, 0], col, 2)
        . center{[fx(fr, x), oy - 0.33, 0]} Math(to_string(x, places), 0.72, col)
    }
}
let YTicks = |fr, ys, col = SLATE, places = 0| block {
    let ox = fx(fr, clamp(fr[0], 0, fr[1]))
    for (y in ys) {
        . Seg([ox - 0.07, fy(fr, y), 0], [ox + 0.07, fy(fr, y), 0], col, 2)
        . center{[ox - 0.36, fy(fr, y), 0]} Math(to_string(y, places), 0.72, col)
    }
}

# faint grid lines at the listed data values
let GridLines = |fr, xs, ys, col = MIST| block {
    for (x in xs) {
        . Seg(at(fr, x, fr[2]), at(fr, x, fr[3]), col, 1.5)
    }
    for (y in ys) {
        . Seg(at(fr, fr[0], y), at(fr, fr[1], y), col, 1.5)
    }
}

# the graph of f over [a, b], drawn in the frame. values are clamped to the window
let Graph = |fr, f, a, b, col = AZURE, w = 4, n = 160|
    stroke{col, w} Polyline(map(sample(a, b, n), |x| at(fr, x, clamp(fr[2], f(x), fr[3]))))

# the region between the graph of f and the x axis over [a, b]
let AreaUnder = |fr, f, a, b, col = AZURE, amount = 0.2, n = 80| {
    var pts = [at(fr, a, 0)]
    for (x in sample(a, b, n)) {
        pts .= at(fr, x, clamp(fr[2], f(x), fr[3]))
    }
    pts .= at(fr, b, 0)
    return fill{tint(col, amount)} stroke{alpha{0} col, 0} Polygon(pts)
}

let G = 9.8
# plot furniture: grid, left and bottom edges, numbers along the edges, names
let Panel = |f, gx, gy, lx, ly, xname, title, col = SLATE| block {
    . GridLines(f, gx, gy)
    . Path([at(f, f[0], f[3]), at(f, f[0], f[2]), at(f, f[1], f[2])], SLATE, 2.5)
    for (x in lx) {
        . center{[fx(f, x), fy(f, f[2]) - 0.3, 0]} Math(to_string(x), 0.72, SLATE)
    }
    for (y in ly) {
        . center{[fx(f, f[0]) - 0.36, fy(f, y), 0]} Math(to_string(y), 0.72, SLATE)
    }
    . center{[(fx(f, f[0]) + fx(f, f[1])) / 2, fy(f, f[2]) - 0.64, 0]} Note(xname, 0.72)
    . center{[(fx(f, f[0]) + fx(f, f[1])) / 2, fy(f, f[3]) + 0.3, 0]} Cap(title, 0.74, col)
}
# position of a projectile launched from the origin at speed v0 and angle deg, after t seconds
let px = |v0, deg, t| v0 * cos(deg_to_rad(deg)) * t
let py = |v0, deg, t| v0 * sin(deg_to_rad(deg)) * t - 0.5 * G * t * t
let flight = |v0, deg| 2 * v0 * sin(deg_to_rad(deg)) / G
# the path flown up to time t, drawn in frame f
let Flown = |f, v0, deg, t, col, w = 4| {
    let n = to_int(max(2, ceil(t * 24)))
    return stroke{col, w} Polyline(map(sample(0, max(t, 0.02), n), |u| at(f, px(v0, deg, u), py(v0, deg, u))))
}
let Arrow2 = |tail, vec, col, w = 4| Tip(tail, [tail[0] + vec[0], tail[1] + vec[1], 0], col, w, 0.17)