Cannon Shot With Air Resistance

You're a 1 5 th 15^\text{th} century ballistics expert serving under the great Ottoman general Sultan Mehmed the Conqueror, tasked with ensuring a solid connection between cannon fire and the heavily fortified city walls of Constantinople.

You're setting up the cannon, which has a muzzle velocity of v 0 = 300 m / s , v_0 = \SI[per-mode=symbol]{300}{\meter\per\second}, for a shot at a crucial encampment some 2 000 m \SI{2000}{\meter} away at the heart of the city when a few upstarts in your outfit start yelling at you, upset that you insist upon careful evaluation of the flight path of the cannonball, and urge you to take a more freewheeling approach. Historians will later note a band of Ottomans screaming at a dejected engineer, "just let it rip."

You hold steady and tell them to find something else to do.

Suppose you allowed the yahoos to have their way and ignored the effects of wind drag. By what margin ( ( in m ) \si{\meter}) would your cannon fire undershoot the encampment?


Assume that the force of wind resistance has the form F drag = 1 2 ρ air C d A v 2 v ^ , \mathbf{F}_\textrm{drag} = -\frac12 \rho_\textrm{air}C_d Av^2 \hat{\mathbf{v}}, where v ^ \hat{\mathbf{v}} is a unit vector in the direction of the total velocity v , \mathbf{v}, A A is the cross-sectional area of the cannonball, and the constants are as defined in the code box below (in SI units). Moreover, the cannonball is a steel sphere of radius r r and density ρ steel . \rho_\textrm{steel}. To avoid collateral damage, you only choose launch angles θ 40 ° . \theta \geq \SI{40}{\degree}. For historical context, read on the Fall of Constantinople .

import math

rho_air = 1.22
g = 10.0
rho_steel = 8050.0
v0 = 300.0
r = 0.08
theta = # Fill this in.
drag = "Off" # Set this to "On"  or "Off" to include drag, or not.
C_d = (1 if drag is "On" else 0)

(vx, vy) = (v0 * math.cos(theta * math.pi / 180), v0 * math.sin(theta * math.pi / 180))
(x, y) = (0, 0)

dt = 0.001

while y >= 0:
    # Finish this code to step through the motion of the cannonball.
    (x, y) = (x + ..., y + ...)
    (vx, vy) = (vx + ..., vy + ...)
    
print("The cannonball's range is {:.2f} meters.".format(x))
    
Python 3
You need to be connected to run code


The answer is 1589.03.

This section requires Javascript.
You are seeing this because something didn't load right. We suggest you, (a) try refreshing the page, (b) enabling javascript if it is disabled on your browser and, finally, (c) loading the non-javascript version of this page . We're sorry about the hassle.

2 solutions

Mark Hennings
Oct 10, 2017

If we were to ignore air resistance, we would aim the gun at an angle θ \theta , where v 0 2 sin 2 θ g = 2000 \frac{v_0^2\sin2\theta}{g} = 2000 , and hence sin 2 θ = 2 9 \sin2\theta = \tfrac29 . Since θ 4 0 \theta \ge 40^\circ , we deduce that θ = 83.580 2 \theta = 83.5802^\circ .

With air resistance, the equation of motion of the cannon-ball is 4 3 π r 3 ρ steel r ¨ = 1 2 ρ air π r 2 r ˙ r ˙ 4 3 π r 3 ρ steel g ( 0 1 ) r ¨ = 3 ρ air 8 ρ steel r r ˙ r ˙ g ( 0 1 ) \begin{aligned} \tfrac43\pi r^3 \rho_{\text{steel}} \ddot{\mathbf{r}} & = -\tfrac12\rho_{\text{air}} \pi r^2 |\dot{\mathbf{r}}| \dot{\mathbf{r}} - \tfrac43\pi r^3 \rho_{\text{steel}} g \binom{0}{1} \\ \ddot{\mathbf{r}} & = \; -\frac{3\rho_{\text{air}}}{8\rho_{\text{steel}} r}|\dot{\mathbf{r}}| \dot{\mathbf{r}} - g\binom{0}{1} \end{aligned} If we solve this equation numerically (I used d t = 0.0001 dt = 0.0001 for sufficient accuracy) with r ( 0 ) = ( 0 0 ) r ˙ ( 0 ) = 300 ( cos 83.580 2 sin 83.580 2 ) \mathbf{r}(0) \; = \; \binom{0}{0} \hspace{2cm} \dot{\mathbf{r}}(0) \; = \; 300\binom{\cos83.5802^\circ}{\sin83.5802^\circ} we deduce that the cannon-ball hits the ground at the point ( 410.97 0 ) \binom{410.97}{0} which represents a range short-fall of 1589.03 \boxed{1589.03} meters.

It is worth noting that the angle of projection needed to reach the target, taking air resistance into account, is roughly θ = 42.0 6 \theta = 42.06^\circ .

1
2
3
4
5
while y >= 0:
    ax = - C_d * (3 * rho_air * math.sqrt(vx ** 2 + vy ** 2) * vx)/(8 * rho_steel * r)
    ay = - C_d * (3 * rho_air * math.sqrt(vx ** 2 + vy ** 2) * vy)/(8 * rho_steel * r) - g
    (x, y) = (x + vx * dt + 0.5 * ax * dt ** 2, y + vy * dt + 0.5 * ay * dt ** 2)
    (vx, vy) = (vx + ax * dt, vy + ay * dt)

I am probably missing something quite simple, but... why is sin2(theta) = 2/9? where did that come from?

Matthew Agona - 3 years, 8 months ago

Log in to reply

Try v 0 = 300 v_0=300 and g = 10 g=10 in the stated equation for the range.

Mark Hennings - 3 years, 8 months ago

Log in to reply

I just never noticed an initial velocity stated in the original problem. but I am noticing it in the python script now.

Matthew Agona - 3 years, 8 months ago
Arjen Vreugdenhil
Oct 12, 2017

I do object to the Ottoman invasion and the siege of Constantinople. If I could change history, I'd let the yahoos have their way and laugh at their lopping of projectiles on their own siegeworks. Or, I would take my place on the city wall and shoot at an angle of about 4 2 42^\circ into the Ottoman invaders, which would give the proper range of 2000 m.

Note that in my simulation I use Δ x = 1 2 ( v old + v new ) d t . \Delta \vec x = \tfrac12(\vec v_{\text{old}} + \vec v_{\text{new}})\:dt. It is a very simple way to obtain more accuracy.

 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
import math

rho_air = 1.22
g = 10.0
rho_steel = 8050.0
v0 = 300.0
r = 0.08
ran = 2000
drag = "On" # Set this to "On"  or "Off" to include drag, or not.
C_d = (1 if drag is "On" else 0)

theta = 90 - math.asin(ran*g/(v0*v0))/2 * 180/math.pi

print("The launch angle is {:.4f} degrees.".format(theta))

(vx, vy) = (v0 * math.cos(theta * math.pi / 180), v0 * math.sin(theta * math.pi / 180))
(x, y) = (0, 0)

dt = 0.001
A = math.pi * r*r
m = 4*math.pi/3 * r*r*r * rho_steel

while y >= 0:
    v2 = vx*vx + vy*vy
    Fd = -0.5*rho_air*C_d*A*v2
    v = math.sqrt(v2)
    (Fdx, Fdy) = (Fd*vx/v, Fd*vy/v)
    (ax, ay) = (Fdx/m, Fdy/m - g)
    (ovx, ovy) = (vx, vy)
    (vx, vy) = (vx + ax*dt, vy + ay*dt)
    (x, y) = (x + (vx+ovx)/2*dt, y + (vy+ovy)/2*dt)

print("The cannonball's range is {:.2f} meters.".format(x))

Output:

1
2
The launch angle is 83.5802 degrees.
The cannonball's range is 410.93 meters.

Your method gives v x = v x + a x × d t v y = v y + a y × d t x = x + 1 2 ( o v x + v x ) d t = x + v x × d t + 1 2 a x × d t 2 y = y + 1 2 ( o v y + v y ) d t = y + v y × d t + 1 2 a y × d t 2 \begin{array}{ccccccc} vx & = & vx + ax \times dt & \hspace{3cm} & vy & = & vy + ay \times dt \\ x & = & x + \tfrac12(ovx + vx)dt \; = \; x + vx \times dt + \tfrac12ax \times dt^2 & & y & = & y + \tfrac12(ovy + vy)dt \; = \; y + vy \times dt + \tfrac12ay \times dt^2 \end{array} which are my formulae (except that mine do not introduce o v x ovx and o v y ovy ). This method gives no greater accuracy.

Mark Hennings - 3 years, 8 months ago

Log in to reply

I noticed that. I was comparing with the more naive method, suggested by the template, which takes Δ x = v new Δ t . \Delta \vec x = \vec v_{\text{new}}\:\Delta t.

Arjen Vreugdenhil - 3 years, 8 months ago

The advantage of my method is that it avoid squaring d t dt (big whoop, of course, with how fast computers are today); and I like the intuition in Δ x = v average Δ t \Delta \vec x = \vec v_{\text{average}}\:\Delta t . However, any difference there is is mostly a matter of preference.

Arjen Vreugdenhil - 3 years, 8 months ago

Yes, trap rule is both more accurate and more numerically stable than the explicit Euler. Although the implicit Euler is more stable than trap rule (but still less accurate).

Steven Chase - 3 years, 8 months ago

0 pending reports

×

Problem Loading...

Note Loading...

Set Loading...