SageMath 示範:物理學的平面拋體運動(Projectile Motion)¶

本 notebook 用 SageMath(符號計算 + 數值 + 圖形)說明經典的「平面拋體運動」:

  • 建立運動方程(含參數)
  • 推導軌跡方程(消去時間)
  • 計算飛行時間、射程、最高點
  • 用圖形驗證並做參數掃描

假設:無空氣阻力、重力加速度恆定、發射點與落點在同一高度(除非另行設定)。

1. 物理模型與符號設定¶

1.1 參數與變數¶

  • $t$:時間(秒)
  • $x(t), y(t)$:位置(公尺)
  • $v_0$:初速度大小(m/s)
  • $\theta$:仰角(弧度)
  • $g$:重力加速度(m/s²),地表常用 $g\approx 9.8$

1.2 初始條件(可改)¶

  • 初始位置:$(x_0,y_0)$
  • 初速度分量: $ v_{x0}=v_0\cos\theta,\quad v_{y0}=v_0\sin\theta $

1.3 運動方程(無阻力)¶

$ x(t)=x_0+v_{x0}t,\quad y(t)=y_0+v_{y0}t-\frac12gt^2 $

下面用 SageMath 建立符號式。

In [1]:
# 符號變數
var('t v0 theta g x0 y0')

# 速度分量
vx0 = v0*cos(theta)
vy0 = v0*sin(theta)

# 位置隨時間
x_t = x0 + vx0*t
y_t = y0 + vy0*t - (g/2)*t^2

x_t, y_t
Out[1]:

2. 消去時間得到軌跡方程(拋物線)¶

由 $x(t)=x_0+v_0\cos\theta\,t$ 得 $ t=\frac{x-x_0}{v_0\cos\theta} $ 代入 $y(t)$ 得到 $y$ 與 $x$ 的關係(拋物線)。

用 Sage 直接做代入與化簡。

In [2]:
var('x y')

t_expr = (x - x0)/(v0*cos(theta))
y_of_x = y0 + vy0*t_expr - (g/2)*t_expr^2
y_of_x_simplified = simplify(y_of_x)
y_of_x_simplified
Out[2]:

這就是常見的拋體軌跡: $ y = y_0 + (x-x_0)\tan\theta - \frac{g}{2v_0^2\cos^2\theta}(x-x_0)^2 $

你可以用 simplify(...) 驗算與課本公式一致。


3. 飛行時間、最高點、射程(同高度落地)¶

3.1 落地條件(同高度)¶

若 $y_0=0$ 且落地高度也是 0:令 $y(t)=0$ 解 t(非零解即飛行時間)

$ 0 = v_0\sin\theta\,t-\frac12gt^2 \Rightarrow t_f=\frac{2v_0\sin\theta}{g} $

3.2 射程(range)¶

$ R = x(t_f)-x_0 = v_0\cos\theta\cdot t_f = \frac{v_0^2\sin(2\theta)}{g} $

3.3 最高點¶

速度 y 分量: $ v_y(t)=v_0\sin\theta-gt $ 最高點 $v_y=0\Rightarrow t_{top}=v_0\sin\theta/g$

最高高度(相對 y0): $ H = \frac{v_0^2\sin^2\theta}{2g} $

下面用 Sage 解與驗算。

In [3]:
# 先設定常用條件:x0=0, y0=0
x0_val, y0_val = 0, 0

y_t0 = y_t.subs({x0:x0_val, y0:y0_val})
# 解 y(t)=0 的 t
sol_t = solve(y_t0 == 0, t)
sol_t
Out[3]:
In [4]:
# 取非零解作為飛行時間 t_f
tf = [s.rhs() for s in sol_t if s.rhs() != 0][0]
tf_simplified = simplify(tf)
tf_simplified
Out[4]:
In [5]:
# 射程 R = x(tf) - x0
x_t0 = x_t.subs({x0:x0_val})
R = simplify(x_t0.subs(t=tf_simplified) - x0_val)
R
Out[5]:
In [6]:
# 最高點時間與高度
vy_t = diff(y_t0, t)
t_top = solve(vy_t == 0, t)[0].rhs()
H = simplify(y_t0.subs(t=t_top))

vy_t, t_top, H
Out[6]:

4. 數值例子:畫出軌跡、標記最高點與落點¶

設定:

  • $v_0=20$ m/s
  • $\theta=45^\circ$
  • $g=9.8$ m/s²
  • $x_0=y_0=0$

我們同時用:

  • 參數式:$(x(t),y(t))$
  • 軌跡式:$y(x)$

並標出:最高點、落點。

In [7]:
# 數值參數
v0_num = 20
theta_num = pi/4
g_num = 9.8

# 代入
x_num = x_t.subs({x0:0, v0:v0_num, theta:theta_num})
y_num = y_t.subs({x0:0, y0:0, v0:v0_num, theta:theta_num, g:g_num})

# 飛行時間、射程、最高點(數值)
tf_num = N(tf_simplified.subs({v0:v0_num, theta:theta_num, g:g_num}))
R_num = N(R.subs({v0:v0_num, theta:theta_num, g:g_num}))
t_top_num = N(t_top.subs({v0:v0_num, theta:theta_num, g:g_num}))
H_num = N(H.subs({v0:v0_num, theta:theta_num, g:g_num}))

tf_num, R_num, t_top_num, H_num
Out[7]:
In [8]:
# 參數式 2D 圖:t 從 0 到 tf
traj = parametric_plot((x_num, y_num), (t, 0, tf_num), thickness=2)

# 標記點:起點、最高點、落點
start = point((0, 0), size=40)
top_pt = point((N(x_num.subs(t=t_top_num)), H_num), size=50)
end_pt = point((R_num, 0), size=40)

traj + start + top_pt + end_pt
Out[8]:
No description has been provided for this image

你也可以畫出 $y(x)$ 的顯式拋物線(在 x ∈ [0,R]):

In [9]:
y_x_num = y_of_x_simplified.subs({x0:0, y0:0, v0:v0_num, theta:theta_num, g:g_num})
plot(y_x_num, (x, 0, R_num), thickness=2)
Out[9]:
No description has been provided for this image

5. 參數掃描:不同仰角的射程與軌跡疊圖¶

固定 $v_0$ 與 g,改變 $\theta$(例如 20°, 35°, 45°, 55°, 70°)。

你會看到:

  • 仰角越大,最高點越高,但射程不一定更遠
  • 在同高度落地且無阻力時,射程最大在 45°(課本結論)

下面用 Sage 直接疊圖。

In [10]:
v0_num = 20
g_num = 9.8
angles_deg = [20, 35, 45, 55, 70]
angles = [a*pi/180 for a in angles_deg]

plots = Graphics()   # <-- key change
for th in angles:
    tf_n = N((2*v0*sin(theta)/g).subs({v0:v0_num, theta:th, g:g_num}))
    x_n = x_t.subs({x0:0, v0:v0_num, theta:th})
    y_n = y_t.subs({x0:0, y0:0, v0:v0_num, theta:th, g:g_num})
    plots += parametric_plot((x_n, y_n), (t, 0, tf_n))

plots
Out[10]:
No description has been provided for this image

射程 vs 仰角(數值表)¶

In [11]:
rows = []
for a_deg, th in zip(angles_deg, angles):
    Rn = N((v0^2*sin(2*theta)/g).subs({v0:v0_num, theta:th, g:g_num}))
    rows.append([a_deg, Rn])
table(rows, header_row=["theta (deg)", "Range R (m)"])
Out[11]:
theta (deg) Range R (m)

6. 非同高度落地(延伸):給定初始高度 y0¶

若 $y_0>0$,落地條件:$y(t)=0$ 解 t(取正根),射程:$x(t_f)-x_0$。

例:

  • $y_0=5$ m
  • $v_0=20$ m/s
  • $\theta=35^\circ$
  • $g=9.8$

用 Sage 解出 $t_f$ 並畫軌跡。

In [12]:
# 參數
v0_num = 20
theta_num = 35*pi/180
g_num = 9.8
y0_num = 5

x_num = x_t.subs({x0:0, v0:v0_num, theta:theta_num})
y_num = y_t.subs({x0:0, y0:y0_num, v0:v0_num, theta:theta_num, g:g_num})

# 解 y(t)=0 的正根作飛行時間
sol_tf = solve(y_num == 0, t)
sol_tf
Out[12]:
In [13]:
tf_candidates = [s.rhs() for s in sol_tf]
tf_candidates_n = [N(c) for c in tf_candidates]
tf_candidates_n
Out[13]:
In [14]:
tf_num = max(tf_candidates_n)  # 取較大的正根(落地時刻)
R_num = N(x_num.subs(t=tf_num))

traj = parametric_plot((x_num, y_num), (t, 0, tf_num), thickness=2)
traj + point((0, y0_num), size=40) + point((R_num, 0), size=40)
Out[14]:
No description has been provided for this image

7. 小結與建議練習¶

你剛剛用 SageMath 做到:

  • 符號推導:從 $x(t),y(t)$ 推出 $y(x)$,推導射程/最高點等公式
  • 數值計算:代入具體參數得到數值結果
  • 圖形驗證:畫出參數式軌跡、疊圖比較不同仰角
  • 延伸情況:初始高度不為 0 的落地時間與射程

建議練習¶

  1. 固定 $v_0=30$、$g=9.8$,掃描角度 $1°~89°$,找射程最大角度(應接近 $45°$)。
  2. 把 g 改成月球重力(約 1.62),比較射程與最高點如何改變。
    3.(進階)加入空氣阻力模型(需要微分方程數值解),比較與無阻力差異。

從這個例子,也感覺到計算軟體可以做模擬計算,增加對物理現象的理解呢!