Python: How do i determine the angle that makes the ball travel the furthest when throwing?

Viewed 260

Edit: I realized now that 180 degrees is wrong, it should have been from 0-90 degrees, so edited that. sorry.

First time asking a question on Stackoverflow so I'm so sorry if I've done anything wrong.

Usually I try to google my way to my answers but this time I have absolutely zero clue, and the only place where it looks like I could find a similar task was on wired, but the links does not work unfortunately.

My problem: I'm attempting to show in a graph what angle is the best angle to throw at in order to make the ball travel the furthest. So far I have been able to draw all possible outcomes when thrown at any angle between 0 and 90. However this looks really messy, how can I make it so that the furthest distance on the x axis is "highlighted".

I do know that 45 degrees is the best angle, and I guess I could just hardcode it in, but is there another (simple) way to show it?

See the link further down for the results i get with my current code.

My code:

import matplotlib.pyplot as plt

x0 = 0.0 # Startposition on x-axis
y0 = 0.0 # Startposition on y-axis
v0 = 10.0 # Startvelocity
g = 9.81 # Gravity
dt = 0.01 # Time resolution (number of seconds per time step)
N = 200 # Amount of time steps
th0 = 0.0 # The angle the ball is thrown at

# Calculations
x = np.zeros((1, N))
y = np.zeros((1, N))

# I begin with this as i want to test all angles between 0 (horizontal) and up to 90(straight up)
for th0 in range(90):   
    for k in range(N):
        x[0,k] = x0 + v0*np.cos(th0*np.pi/180.0)*dt*k # motion equation on x-axis. No acceleration
        y[0,k] = y0 + v0*np.sin(th0*np.pi/180.0)*dt*k - 0.5*g*(dt*k)*(dt*k) # motion equation on y-axis. gravity acceleration.
    plt.plot(x[0,:], y[0,:])
    plt.plot([0,12],[0,0])
    th0=th0+1
plt.grid()
plt.axis([0, 12, 0, 12])
plt.show()

As u can see in the image linked below, everything is kinda messy, i wish i could highlight the line at which the ball travels the furthest and the angle it is thrown at. here

Again sorry if my english is terrible or if ive done anything else the wrong way. I speed translated the code, so some of the comments may be a bit weird.

Edit2: I want it to look kind of like the picture below, just without the hardcoding, however i might have a solution, just due to my exams i dont have time to look more at it atm. If anyone ever comes across this and is wondering about the same let me know. If not i guess ill just close this (if thats even possible).

this

1 Answers

You can calculate the best angle analytically:

y = -g/2*t**2 + v*sin(theta)*t

# Require y == 0 for t > 0:
t = 2*v/g * sin(theta)
x = v*cos(theta) * 2*v/g*sin(theta)

# Compute the derivative of 'x' with respect to 'theta':
xp = 2*v**2/g * (cos(theta)**2 - sin(theta)**2)

# Require xp == 0 to find the maximum.
# From this follows that `cos(theta)**2 = sin(theta)**2`.
theta = pi/4

So the result is indeed pi/4 or 45 degrees. You can use this information to color your plot:

import matplotlib.pyplot as plt
import numpy as np

v, g = 10, 9.81

def compute_xy(theta):
    t_max = 2*v/g * np.sin(theta)
    t = np.linspace(0, t_max, 100)
    x = v * np.cos(theta) * t
    y = -g/2 * t**2 + v*np.sin(theta)*t
    return x, y

fig, ax = plt.subplots()
ax.set(xlabel='x [m]', ylabel='y [m]')

for theta in np.linspace(0, np.pi/2, 100):
    ax.plot(*compute_xy(theta), '-', color='#1f77b4', lw=0.7, alpha=0.4)

# Best trajectory:
ax.plot(*compute_xy(np.pi/4), '-', color='#ff7f0e', lw=2, label='Optimal')
ax.legend()

plt.show()

Example plot showing trajectories

Alternatively you can precompute all trajectories and then find the one with the largest x-range:

import matplotlib.pyplot as plt
import numpy as np

v, g = 10, 9.81

def compute_xy(theta):
    t_max = 2*v/g * np.sin(theta)
    t = np.linspace(0, t_max, 100)
    x = v * np.cos(theta) * t
    y = -g/2 * t**2 + v*np.sin(theta)*t
    return x, y

thetas = np.linspace(0, np.pi/2, 100)
trajectories = np.stack([compute_xy(t) for t in thetas])
best_index = np.argmax(trajectories[:, 0, -1])
print(f'Best angle: {thetas[best_index]/np.pi:.2f} [pi]')

fig, ax = plt.subplots()
ax.set(xlabel='x [m]', ylabel='y [m]')
ax.plot(*trajectories.reshape(-1, len(thetas)), '-', color='#1f77b4', lw=0.7, alpha=0.4)
ax.plot(*trajectories[best_index], '-', color='#ff7f0e', lw=2, label='Optimal')
ax.legend()

plt.show()
Related