187 lines
6.9 KiB
Python
187 lines
6.9 KiB
Python
import matplotlib.pyplot as plt
|
||
import numpy as np
|
||
|
||
# Параметры задачи
|
||
L = 20 # расстояние до стены (м)
|
||
H = 8 # высота стены (м)
|
||
g = 9.81 # ускорение свободного падения
|
||
|
||
print(f"Параметры задачи:")
|
||
print(f"Расстояние до стены L = {L} м")
|
||
print(f"Высота стены H = {H} м")
|
||
print()
|
||
|
||
# Расчет оптимальных параметров
|
||
R = np.sqrt(L**2 + H**2) # расстояние до верхнего края стены
|
||
tan_alpha_opt = (L + R) / H
|
||
alpha_opt_rad = np.arctan(tan_alpha_opt)
|
||
alpha_opt_deg = np.degrees(alpha_opt_rad)
|
||
|
||
# Минимальная скорость
|
||
v0_min = np.sqrt(g * (L**2 + H**2 + L * R) / L)
|
||
|
||
print(f"Результаты расчета:")
|
||
print(f"Расстояние до верхнего края стены R = {R:.2f} м")
|
||
print(f"Оптимальный угол α = {alpha_opt_deg:.1f}°")
|
||
print(f"Минимальная скорость v₀ = {v0_min:.2f} м/с")
|
||
print(f"tan(α) = {tan_alpha_opt:.3f}")
|
||
print()
|
||
|
||
|
||
# Функция для расчета траектории
|
||
def trajectory(v0, alpha_rad, t_max):
|
||
t = np.linspace(0, t_max, 1000)
|
||
x = v0 * np.cos(alpha_rad) * t
|
||
y = v0 * np.sin(alpha_rad) * t - 0.5 * g * t**2
|
||
return x, y, t
|
||
|
||
|
||
# Время полета для оптимальной траектории
|
||
t_optimal = 2 * v0_min * np.sin(alpha_opt_rad) / g
|
||
|
||
# Построение графика
|
||
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(14, 12))
|
||
|
||
# График 1: Сравнение траекторий
|
||
# Оптимальная траектория
|
||
x_opt, y_opt, t_opt = trajectory(v0_min, alpha_opt_rad, t_optimal)
|
||
|
||
# Проверим, что траектория проходит через точку (L, H)
|
||
t_at_wall = L / (v0_min * np.cos(alpha_opt_rad))
|
||
y_at_wall = v0_min * np.sin(alpha_opt_rad) * t_at_wall - 0.5 * g * t_at_wall**2
|
||
print(f"Проверка: высота в точке x=L составляет {y_at_wall:.3f} м (должно быть {H} м)")
|
||
|
||
ax1.plot(
|
||
x_opt,
|
||
y_opt,
|
||
"r-",
|
||
linewidth=3,
|
||
label=f"Оптимальная (α={alpha_opt_deg:.1f}°, v₀={v0_min:.1f}м/с)",
|
||
)
|
||
|
||
# Сравнение с другими углами (при больших скоростях)
|
||
angles_comp = [30, 45, 60, 75]
|
||
colors = ["blue", "green", "orange", "purple"]
|
||
|
||
for angle, color in zip(angles_comp, colors):
|
||
alpha_rad = np.radians(angle)
|
||
# Скорость, необходимая для данного угла
|
||
# Из условия: L*tan(α) - gL²/(2v²cos²α) = H
|
||
cos_alpha = np.cos(alpha_rad)
|
||
tan_alpha = np.tan(alpha_rad)
|
||
|
||
if L * tan_alpha > H: # Траектория может пройти над стеной
|
||
v_needed = np.sqrt(g * L**2 / (2 * cos_alpha**2 * (L * tan_alpha - H)))
|
||
t_flight = 2 * v_needed * np.sin(alpha_rad) / g
|
||
x_traj, y_traj, _ = trajectory(v_needed, alpha_rad, t_flight)
|
||
|
||
ax1.plot(
|
||
x_traj,
|
||
y_traj,
|
||
"--",
|
||
color=color,
|
||
linewidth=2,
|
||
label=f"{angle}° (v₀={v_needed:.1f}м/с)",
|
||
)
|
||
print(f"Для угла {angle}° требуется скорость {v_needed:.2f} м/с")
|
||
|
||
# Стена
|
||
ax1.plot([L, L], [0, H], "k-", linewidth=5, label="Стена")
|
||
ax1.plot([L - 0.5, L + 0.5], [H, H], "k-", linewidth=5)
|
||
|
||
# Точка броска
|
||
ax1.plot(0, 0, "ko", markersize=8, label="Точка броска")
|
||
|
||
# Критическая точка (L, H)
|
||
ax1.plot(L, H, "ro", markersize=8, label="Критическая точка")
|
||
|
||
ax1.set_xlim(-2, 50)
|
||
ax1.set_ylim(-2, 25)
|
||
ax1.set_xlabel("Расстояние (м)")
|
||
ax1.set_ylabel("Высота (м)")
|
||
ax1.set_title("Сравнение траекторий для перелета через стену")
|
||
ax1.grid(True, alpha=0.3)
|
||
ax1.legend()
|
||
|
||
# График 2: Зависимость скорости от угла
|
||
angles = np.linspace(15, 89, 100)
|
||
speeds = []
|
||
|
||
for angle in angles:
|
||
alpha_rad = np.radians(angle)
|
||
cos_alpha = np.cos(alpha_rad)
|
||
tan_alpha = np.tan(alpha_rad)
|
||
|
||
if L * tan_alpha > H:
|
||
v_req = np.sqrt(g * L**2 / (2 * cos_alpha**2 * (L * tan_alpha - H)))
|
||
speeds.append(v_req)
|
||
else:
|
||
speeds.append(np.inf) # Невозможно перелететь
|
||
|
||
# Убираем бесконечные значения для графика
|
||
angles_valid = []
|
||
speeds_valid = []
|
||
for angle, speed in zip(angles, speeds):
|
||
if speed < 100: # Ограничиваем для наглядности
|
||
angles_valid.append(angle)
|
||
speeds_valid.append(speed)
|
||
|
||
ax2.plot(angles_valid, speeds_valid, "b-", linewidth=2, label="Требуемая скорость")
|
||
ax2.axhline(
|
||
y=v0_min,
|
||
color="r",
|
||
linestyle="--",
|
||
linewidth=2,
|
||
label=f"Минимум = {v0_min:.2f} м/с",
|
||
)
|
||
ax2.axvline(
|
||
x=alpha_opt_deg,
|
||
color="r",
|
||
linestyle="--",
|
||
linewidth=2,
|
||
label=f"Оптимальный угол = {alpha_opt_deg:.1f}°",
|
||
)
|
||
ax2.plot(alpha_opt_deg, v0_min, "ro", markersize=10, label="Оптимум")
|
||
|
||
# Минимальный угол для возможности перелета
|
||
alpha_min = np.degrees(np.arctan(H / L))
|
||
ax2.axvline(
|
||
x=alpha_min,
|
||
color="gray",
|
||
linestyle=":",
|
||
alpha=0.7,
|
||
label=f"Мин. угол = {alpha_min:.1f}°",
|
||
)
|
||
|
||
ax2.set_xlim(15, 90)
|
||
ax2.set_ylim(15, 50)
|
||
ax2.set_xlabel("Угол броска (градусы)")
|
||
ax2.set_ylabel("Требуемая скорость (м/с)")
|
||
ax2.set_title("Зависимость требуемой скорости от угла броска")
|
||
ax2.grid(True, alpha=0.3)
|
||
ax2.legend()
|
||
|
||
plt.tight_layout()
|
||
plt.show()
|
||
|
||
# Дополнительные расчеты
|
||
print(f"\nДополнительная информация:")
|
||
print(f"Минимальный возможный угол: {alpha_min:.1f}° (arctan(H/L))")
|
||
print(f"Превышение оптимального угла над 45°: {alpha_opt_deg - 45:.1f}°")
|
||
|
||
# Сравнение с броском под 45° на максимальную дальность
|
||
v_45_max_range = np.sqrt(g * L) # Скорость для максимальной дальности L
|
||
print(f"Скорость для броска на дальность L под 45°: {v_45_max_range:.2f} м/с")
|
||
print(f"Увеличение скорости из-за стены: {(v0_min/v_45_max_range - 1)*100:.1f}%")
|
||
|
||
# Энергия
|
||
E_min = 0.5 * v0_min**2
|
||
E_45 = 0.5 * v_45_max_range**2
|
||
print(f"Минимальная кинетическая энергия (на единицу массы): {E_min:.1f} Дж/кг")
|
||
print(f"Увеличение энергии из-за стены: {(E_min/E_45 - 1)*100:.1f}%")
|
||
|
||
# Максимальная высота оптимальной траектории
|
||
h_max = v0_min**2 * np.sin(alpha_opt_rad) ** 2 / (2 * g)
|
||
print(f"Максимальная высота оптимальной траектории: {h_max:.2f} м")
|
||
print(f"Превышение над стеной: {h_max - H:.2f} м")
|