234 lines
7.5 KiB
Python
234 lines
7.5 KiB
Python
import numpy as np
|
||
import matplotlib.pyplot as plt
|
||
|
||
# Параметры задачи
|
||
h = 10 # высота падения (м)
|
||
alpha_deg = 30 # угол наклона плоскости (градусы)
|
||
alpha = np.radians(alpha_deg) # угол в радианах
|
||
g = 9.81 # ускорение свободного падения
|
||
|
||
print(f"Параметры задачи:")
|
||
print(f"Высота падения h = {h} м")
|
||
print(f"Угол наклона α = {alpha_deg}°")
|
||
print()
|
||
|
||
# Расчет характерных величин
|
||
v0 = np.sqrt(2 * g * h) # скорость при первом ударе
|
||
print(f"Скорость при первом ударе: v₀ = {v0:.2f} м/с")
|
||
|
||
# Компоненты скорости после первого отскока
|
||
v0x = v0 * np.sin(2 * alpha)
|
||
v0y = -v0 * np.cos(2 * alpha)
|
||
print(f"Компоненты скорости после отскока:")
|
||
print(f"v₀ₓ = {v0x:.2f} м/с")
|
||
print(f"v₀ᵧ = {v0y:.2f} м/с")
|
||
|
||
# Время полета между первым и вторым ударами
|
||
t1 = 2 * np.sqrt(2 * h / g) * (4 * np.sin(alpha) ** 2 - 1)
|
||
print(f"Время полета между ударами: t₁ = {t1:.3f} с")
|
||
|
||
# Расстояния между ударами
|
||
L1 = 8 * h * np.sin(alpha) * (4 * np.sin(alpha) ** 2 - 1)
|
||
k = np.cos(2 * alpha) ** 2 # коэффициент уменьшения
|
||
L2 = L1 * k
|
||
L3 = L1 * k**2
|
||
|
||
print(f"\nРасстояния между точками ударов:")
|
||
print(f"L₁ = {L1:.2f} м")
|
||
print(f"L₂ = {L2:.2f} м")
|
||
print(f"L₃ = {L3:.2f} м")
|
||
|
||
# Максимальное удаление от плоскости
|
||
l_max = h * np.sin(3 * alpha) ** 2 / (2 * np.sin(alpha) ** 2)
|
||
print(f"\nМаксимальное удаление от плоскости: l = {l_max:.2f} м")
|
||
|
||
# Максимальная вертикальная высота над плоскостью
|
||
h_max = h * np.sin(2 * alpha) ** 2 / (2 * np.cos(alpha) ** 2)
|
||
print(f"Максимальная вертикальная высота: h_max = {h_max:.2f} м")
|
||
|
||
# Построение графика
|
||
fig, ax = plt.subplots(figsize=(14, 10))
|
||
|
||
# Параметры для визуализации
|
||
x_range = 60
|
||
y_range = 25
|
||
|
||
# Построение наклонной плоскости
|
||
x_plane = np.linspace(-5, x_range, 100)
|
||
y_plane = -x_plane * np.tan(alpha)
|
||
ax.plot(
|
||
x_plane, y_plane, "k-", linewidth=3, label=f"Наклонная плоскость (α = {alpha_deg}°)"
|
||
)
|
||
|
||
# Первое падение (вертикально вниз)
|
||
x_fall = np.array([0, 0])
|
||
y_fall = np.array([h / np.cos(alpha), 0])
|
||
ax.plot(x_fall, y_fall, "r--", linewidth=2, label="Падение с высоты h")
|
||
|
||
|
||
# Функция для построения траектории между ударами
|
||
def plot_trajectory(x0, y0, vx, vy, t_flight, color, label, show_max=False):
|
||
t = np.linspace(0, t_flight, 200)
|
||
x = x0 + vx * t
|
||
y = y0 + vy * t - 0.5 * g * t**2
|
||
|
||
ax.plot(x, y, color=color, linewidth=2, label=label)
|
||
|
||
if show_max:
|
||
# Максимум траектории
|
||
t_max = vy / g
|
||
if t_max > 0 and t_max < t_flight:
|
||
x_max = x0 + vx * t_max
|
||
y_max = y0 + vy * t_max - 0.5 * g * t_max**2
|
||
ax.plot(
|
||
x_max,
|
||
y_max,
|
||
"o",
|
||
color=color,
|
||
markersize=8,
|
||
markerfacecolor="white",
|
||
markeredgecolor=color,
|
||
markeredgewidth=2,
|
||
)
|
||
|
||
# Расстояние от плоскости в точке максимума
|
||
dist_to_plane = (y_max + x_max * np.tan(alpha)) * np.cos(alpha)
|
||
return x_max, y_max, dist_to_plane
|
||
|
||
return None
|
||
|
||
|
||
# Траектория после первого удара
|
||
x1_end = v0x * t1
|
||
y1_end = v0y * t1 - 0.5 * g * t1**2
|
||
max_info = plot_trajectory(
|
||
0, 0, v0x, v0y, t1, "blue", "После 1-го удара", show_max=True
|
||
)
|
||
|
||
# Точки ударов
|
||
impact_points_x = [0]
|
||
impact_points_y = [0]
|
||
|
||
# Второй удар
|
||
impact_points_x.append(x1_end)
|
||
impact_points_y.append(y1_end)
|
||
|
||
# Скорость после второго удара (уменьшается)
|
||
v1x = v0x * np.cos(2 * alpha)
|
||
v1y = -v0y * np.cos(2 * alpha)
|
||
t2 = t1 * np.cos(2 * alpha)
|
||
|
||
# Траектория после второго удара
|
||
x2_end = x1_end + v1x * t2
|
||
y2_end = y1_end + v1y * t2 - 0.5 * g * t2**2
|
||
plot_trajectory(x1_end, y1_end, v1x, v1y, t2, "green", "После 2-го удара")
|
||
|
||
# Третий удар
|
||
impact_points_x.append(x2_end)
|
||
impact_points_y.append(y2_end)
|
||
|
||
# Скорость после третьего удара
|
||
v2x = v1x * np.cos(2 * alpha)
|
||
v2y = -v1y * np.cos(2 * alpha)
|
||
t3 = t2 * np.cos(2 * alpha)
|
||
|
||
# Траектория после третьего удара
|
||
x3_end = x2_end + v2x * t3
|
||
y3_end = y2_end + v2y * t3 - 0.5 * g * t3**2
|
||
plot_trajectory(x2_end, y2_end, v2x, v2y, t3, "orange", "После 3-го удара")
|
||
|
||
# Четвертый удар
|
||
impact_points_x.append(x3_end)
|
||
impact_points_y.append(y3_end)
|
||
|
||
# Отметка точек ударов
|
||
ax.plot(impact_points_x, impact_points_y, "ro", markersize=8, label="Точки ударов")
|
||
|
||
# Нумерация точек ударов
|
||
for i, (x, y) in enumerate(zip(impact_points_x, impact_points_y)):
|
||
ax.annotate(
|
||
f"{i+1}",
|
||
(x, y),
|
||
xytext=(5, 5),
|
||
textcoords="offset points",
|
||
fontsize=12,
|
||
fontweight="bold",
|
||
color="red",
|
||
)
|
||
|
||
# Отметка максимальных точек
|
||
if max_info:
|
||
x_max, y_max, dist_max = max_info
|
||
ax.annotate(
|
||
f"Максимум\n(l={dist_max:.1f}м)",
|
||
(x_max, y_max),
|
||
xytext=(10, 10),
|
||
textcoords="offset points",
|
||
fontsize=10,
|
||
ha="left",
|
||
bbox=dict(boxstyle="round,pad=0.3", facecolor="lightblue", alpha=0.7),
|
||
)
|
||
|
||
# Стрелки для показа расстояний
|
||
mid_x = impact_points_x[1] / 2
|
||
mid_y = impact_points_y[1] / 2
|
||
ax.annotate(
|
||
"",
|
||
xy=(impact_points_x[1], impact_points_y[1]),
|
||
xytext=(impact_points_x[0], impact_points_y[0]),
|
||
arrowprops=dict(arrowstyle="<->", color="purple", lw=2),
|
||
)
|
||
ax.text(
|
||
mid_x,
|
||
mid_y - 1,
|
||
f"L₁ = {L1:.1f}м",
|
||
ha="center",
|
||
bbox=dict(boxstyle="round,pad=0.3", facecolor="white", alpha=0.8),
|
||
)
|
||
|
||
# Настройка графика
|
||
ax.set_xlim(-2, x_range)
|
||
ax.set_ylim(-15, y_range)
|
||
ax.set_xlabel("x (м)", fontsize=12)
|
||
ax.set_ylabel("y (м)", fontsize=12)
|
||
ax.set_title(
|
||
"Траектория мячика при упругих отскоках от наклонной плоскости",
|
||
fontsize=14,
|
||
fontweight="bold",
|
||
)
|
||
ax.grid(True, alpha=0.3)
|
||
ax.legend(fontsize=10)
|
||
ax.set_aspect("equal")
|
||
|
||
# Добавление текстовой информации на график
|
||
info_text = f"""Результаты расчетов:
|
||
• L₁ = {L1:.1f} м
|
||
• L₂ = {L2:.1f} м
|
||
• L₃ = {L3:.1f} м
|
||
• l_max = {l_max:.1f} м
|
||
• h_max = {h_max:.1f} м
|
||
|
||
Параметры:
|
||
• h = {h} м
|
||
• α = {alpha_deg}°"""
|
||
|
||
ax.text(
|
||
0.02,
|
||
0.98,
|
||
info_text,
|
||
transform=ax.transAxes,
|
||
fontsize=10,
|
||
verticalalignment="top",
|
||
bbox=dict(boxstyle="round,pad=0.5", facecolor="lightyellow", alpha=0.8),
|
||
)
|
||
|
||
plt.tight_layout()
|
||
plt.show()
|
||
|
||
# Проверка формул для частного случая α = 30°
|
||
print(f"\nПроверка формул для α = {alpha_deg}°:")
|
||
print(f"4sin²α - 1 = {4*np.sin(alpha)**2 - 1:.3f}")
|
||
print(f"cos(2α) = {np.cos(2*alpha):.3f}")
|
||
print(f"sin(3α) = {np.sin(3*alpha):.3f}")
|
||
print(f"sin(2α) = {np.sin(2*alpha):.3f}")
|