Бросок тела под углом к горизонту. Моделируем на Python.

Добрый день, уважаемые читатели CodeBlog. Эта статья является продолжением статьи про бросок тела с высоты. Советую ознакомиться с материалом прошлой статьи из рубрики «Физика», ведь очень много вещей мы разобрали и доказали именно там. Здесь мы будем использовать только формулы, которые мы доказали ранее.
И на повестке дня — бросок тела под углом к горизонту.

Примечание. Те, кто зашёл сюда из интереса к физике, не пугайтесь названия языка программирования в заголовке статьи. Программированию будет посвящен последний раздел, до этого будет лишь обсуждение физических процессов.

Подпишись на группу Вконтакте и Телеграм-канал. Там еще больше полезного контента для программистов.
А на YouTube-канале ты найдешь обучающие видео по программированию. Подписывайся!

Бросаем камень

Предположим, что мы находимся на земле и бросаем камень (или любой другой предмет) под углом \alpha к горизонту (условимся, что земля под ногами идеально ровная, а сопротивления воздуха не существует). Также пусть мы совершаем бросок со скоростью v_0.

Наша задача: изучить, как долго будет лететь камень, какой максимальной высоты он достигнет и сколько пролетит расстояния в горизонтальном направлении. Начнём.

Т.к. мы бросаем камень под углом, разложим скорость (векторную величину) на v_y и v_x, то есть вертикальную и горизонтальную составляющие скорости. Используя прямоугольный треугольник и соотношения тригонометрических функций с его сторонами, получаем v_{y0} = v_0 \cdot sin \alpha, а v_{x0} = v_0 \cdot cos \alpha.

кривой рисуночек треугольника из пейнта авторского создания

Вверх и только вверх!

Тело набирает высоту, пока вертикальная составляющая его скорости не равна нулю. Т.к. на тело действует ускорение свободного падения, которое уменьшает его скорость, закон изменения v_y выглядит таким образом:

    \[v_y = v_{y0} - g \cdot t\]

Приравняв v_y к нулю, мы можем найти время, за которое тело достигает максимальной высоты:

    \[t_p = \frac{v_{y0}}{g} = \frac{v_0 \cdot sin \alpha}{g}\]

Также мы с легкостью можем вычислить высоту, которую достигает наш объект в зависимости от времени:

    \[h = v_{y0} \cdot t - \frac{g \cdot t^2}{2}\]

Примечание. Как проверить правильность этой формулы? Во-первых, проверить размерность. Здесь у нас размерность:

    \[[h] = \frac{m \cdot c}{c} - \frac{m \cdot c^2}{c^2} = m - m = m\]

Во-вторых, воспользоваться математикой. Разумно предположить, что траектория полёта (т. е. график h(t)) является параболой, схожей на график функции f(x) = - x^2. f(x) является выпуклой вверх. Это можно доказать, используя свойство второй производной:

    \[\frac{df}{d^2t} = -2\]

Вторая производная на всех области определения функции отрицательна, то есть функция всегда выпукла вверх. У нас такая же ситуация, ведь:

    \[\frac{dh}{d^2t} = -g\]

Т. к. g — константа равная ~ 10, то вторая производная функции h(t) также всегда отрицательна, т. е. h(t) описывает параболу, выпуклую вверх.

Сколько летит тело?

Т. к. мы не будем учитывать сопротивление воздуха, то горизонтальная составляющая скорости v_x не изменяется, а расстояние, которое пролетело тело в горизонтальном направлении вычисляется по формуле:

    \[l  = v_x \cdot t = v_{x0} \cdot t = v_0 \cdot cos \alpha \cdot t\]

Далее логично предположить, что тело будет упадёт на землю за время, равное двойному времени подъёма на максимальную высоту. Докажем это. Максимальная высота подъёма равна:

    \[h_{max} = \frac{(v_0 \cdot sin \alpha)^2}{2g}.\]

Рассмотрим, за какое кол-во времени тело опустится с такой высоты, учитывая, что на него действует только ускорение свободного падения.

    \[\frac{gt^2}{2} = \frac{(v_0 \cdot sin \alpha)^2}{2g}\]


    \[t^2 = \frac{(v_0 \cdot sin \alpha)^2}{g^2}\]


    \[t = \frac{v_0 \cdot sin \alpha}{g} = t_p\]

Таким образом, время полёта равняется двойному времени подъёма, а точка достижения максимальной высоты находится ровно по центру траектории движения.

Визуализируем траекторию с помощью Python

Для визуализации траектории я буду использовать matplotlib, а для выполнения вычислений — NumPy. Также я установлю стиль для графика с помощью jupyterthemes.jtplot.

In[1]:
import matplotlib.pyplot as plt
import numpy as np
from jupyterthemes import jtplot

jtplot.style('onedork')

Далее мы реализуем функцию, которая будем производить вычисление x и y в зависимости от t.

In[2]:
def plot_trace(v0, alpha, file=None, **kwargs):
    # acceleration of gravity
    g = 9.8066

    # time to max height
    tp = v0 * np.sin(alpha) / g

    # converting to time range
    t = np.linspace(0, 2 * tp, 1000)

    # x axis
    x = v0 * np.cos(alpha) * t

    # y axis
    y = v0 * np.sin(alpha) * t - g * (t**2) / 2

    # change size for figure
    plt.figure(figsize=(20, 10))

    plt.plot(x, y, **kwargs)

    # xlim
    plt.xlim([-1, np.max(x) * 1.1])

    # ylim
    plt.ylim([-1, np.max(y) * 1.1])

    # axis labels
    plt.xlabel('X', fontsize=24)
    plt.ylabel('Y', fontsize=24)

    # chart title
    plt.title(f'v_0 = {v0}, α = {alpha}', fontsize=32)

    plt.grid(True)

    # set legend
    if 'label' in kwargs:
        plt.legend(loc='best', fontsize=32)

    if file is not None:
        plt.savefig(file)

К сожалению, описание базовых функций matplotlib.pyplot выходит за рамки этой статьи, однако если вы не понимаете, что делает та или иная функция, просто введите поисковый запрос типа '<name of function examples>'.

Для v_0 = 30 и \alpha = 0.25 функция работает следующим образом:

In[3]:
plot_trace(30, 0.5, label='trace', color='g')
результат выполнения функции

Заключение

В этой статье мы рассмотрели физику такого процесса, как бросок тела под углом к горизонту и создали функцию отображения траектории полёта, используя язык программирования Python. Данная функция имеет возможность сохранить полученный результат в графический файл, а также всячески настраивать стиль самого графика.

Советую прочитать статью «Производная. Определение и базовые теоремы«.

А также подписывайтесь на группу ВКонтакте, Telegram и YouTube-канал. Там еще больше полезного и интересного для программистов.