Python: Как определить угол, под которым мяч движется дальше всего при броске? - PullRequest
3 голосов
/ 26 мая 2020

Edit: Теперь я понял, что 180 градусов - это неправильно, они должны были быть от 0 до 90 градусов, поэтому отредактировал это. извините.

Первый раз задаю вопрос о Stackoverflow, поэтому мне очень жаль, если я сделал что-то не так.

Обычно я пытаюсь найти свой ответ в Google, но на этот раз у меня абсолютно нулевой ключ к разгадке, и единственное место, где, похоже, я мог бы найти аналогичную задачу, было в проводной сети, но ссылки, к сожалению, не работают.

Моя проблема: я пытаюсь показать на графике, под каким углом это лучший угол для броска, чтобы мяч летел как можно дальше. До сих пор мне удавалось нарисовать все возможные результаты, если бросить его под любым углом от 0 до 90. Однако это выглядит действительно беспорядочно, как я могу сделать так, чтобы самое дальнее расстояние по оси x было «подсвечено».

Я знаю, что 45 градусов - лучший угол, и я думаю, я мог бы просто жестко его закодировать, но есть ли другой (простой) способ показать это?

См. Ссылку ниже для результатов i получить с моим текущим кодом.

Мой код:

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()

Как вы можете видеть на изображении, приведенном ниже, все немного беспорядочно, я wi sh я мог бы выделить строку в под которым мяч проходит дальше всего, и под углом, под которым он брошен. here

Еще раз извините, если мой английский sh ужасен или я сделал что-то еще неправильно. Я быстро перевел код, поэтому некоторые комментарии могут показаться немного странными.

Edit2: Я хочу, чтобы он выглядел как на картинке ниже, только без жесткого кодирования, однако у меня может быть решение, просто из-за экзаменов у меня нет времени больше на него смотреть. Если кто-нибудь когда-нибудь столкнется с этим и задастся вопросом, дайте мне знать. Если нет, я думаю, что плохо, просто закройте это (если это вообще возможно).

this

1 Ответ

2 голосов
/ 27 мая 2020

Вы можете вычислить лучший угол аналитически:

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

Таким образом, результат действительно равен pi/4 или 45 градусов. Вы можете использовать эту информацию для раскрашивания вашего графика:

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

В качестве альтернативы вы можете предварительно вычислить все траектории, а затем найти траекторию с наибольшим x- диапазон:

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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...