跳轉到

01.1 參數曲線與弧長#

本節目標#

  • 理解參數曲線 \(\gamma(t) = (x(t), y(t), z(t))\) 的幾何意義,以及「參數」在曲線上扮演的角色。
  • 學會對位置向量微分: \(\gamma'(t)\) 就是曲線的「速度向量」,其方向為切線方向、大小為速率。
  • 推導並計算弧長積分 \(s=\int\|\gamma'\|\,dt\) 。
  • 認識「以 \(t\) 為參數」與「以弧長 \(s\) 為參數」的差異,理解等速(arc-length)參數化的重要性。
  • 用 SymPy 的 diff、integrate、Matrix 實作上述所有計算。

幾何直覺:一條被「時間」走過的曲線#

想像一隻螞蟻在紙上或空間中爬行。牠在每個時刻 \(t\) 都有一個位置,把所有位置按時間順序連起來,就是一條參數曲線:

\[ \gamma(t) = (x(t), y(t), z(t)), \quad t \in [a, b] \]

關鍵觀念:同一條曲線可以有無限多種參數化。例如 \(\gamma_1(t) = (\cos t, \sin t)\) 與 \(\gamma_2(t) = (\cos 2t, \sin 2t)\) 描出的都是單位圓,但前者花 \(2\pi\) 的「時間」走完一圈,後者只花 \(\pi\) 。曲線(幾何物件)與參數化(走法)是兩件不同的事。

微分幾何學中最重要的不變量之一就是弧長——它不隨參數化改變。

速度向量:對位置向量微分#

把 \(\gamma(t)\) 視為位置向量,對 \(t\) 微分就是對每個分量微分:

\[ \gamma'(t) = (x'(t), y'(t), z'(t)) \]
  • 方向: \(\gamma'(t)\) 指向曲線在該點的切線方向(朝參數增加的方向)。
  • 大小: \(\|\gamma'(t)\| = \sqrt{x'^2 + y'^2 + z'^2}\) 是「速率」,即該瞬間走多快。

若 \(\|\gamma'(t)\| = 1\) 對所有 \(t\) 成立,我們稱 \(\gamma\) 是單位速率(unit-speed)或以弧長為參數的曲線。這是微分幾何最喜歡的參數化,原因將在下一節 Frenet 標架中明朗。

弧長:把每一步的長度加起來#

微小時間 \(dt\) 內,質點移動的距離約為 \(\|\gamma'(t)\|\,dt\) (局部上近似直線)。把所有小段加總,取極限即得積分:

\[ s = \int_a^b \|\gamma'(t)\|\, dt = \int_a^b \sqrt{x'(t)^2 + y'(t)^2 + z'(t)^2}\, dt \]

弧長是幾何量,不依賴參數化的選擇:換參數化只會改變被積函數的樣子,積分值不變。

更進一步,我們可以定義弧長函數

\[ s(t) = \int_a^t \|\gamma'(u)\|\, du \]

若 \(\|\gamma'\| > 0\) (曲線不停在原地), \(s(t)\) 是嚴格遞增函數,可以反解 \(t = t(s)\) ,代入 \(\gamma\) 得到以弧長為參數的新曲線 \(\Gamma(s) = \gamma(t(s))\) 。此時 \(\|\Gamma'(s)\| = 1\) 恆成立——這就是等速參數化:弧長每增加 1,位置恰好沿曲線前進 1 單位。

以 \(t\) 為參數 vs. 以 \(s\) 為參數#

面向 一般參數 \(t\) 弧長參數 \(s\)
物理意義 時間(可快可慢) 沿曲線走了多遠
\(\|\gamma'\|\) 任意(可依 \(t\) 變動) 恆等於 \(1\)
幾何公式 常較複雜(含修正因子) 最簡潔(如曲率 \(\kappa=\|\gamma''\|\) )
SymPy 運算 直接 diff 需先求 \(s(t)\) 再反解,常無初等封閉形式

實務上:大多數曲線(例如螺旋線、一般擺線)的 \(s(t)\) 反解不出初等函數,因此微分幾何發展出「在一般參數下也成立的公式」(見 01.2、01.3 節),讓我們不必真的做反解。但理解弧長參數化的概念,仍是讀懂所有定理的前提。

SymPy 實作:位置向量、速度與弧長#

SymPy 中最自然的做法是用 Matrix 表示 \(\gamma(t)\) ,用 diff 微分,用 norm 取大小,用 integrate 積分。

基本工具#

import sympy as sp

t = sp.symbols('t', real=True)

# 定義一條參數曲線:螺旋線
a, b = sp.symbols('a b', positive=True)
gamma = sp.Matrix([a*sp.cos(t), a*sp.sin(t), b*t])

# 速度向量 = 對 t 微分
velocity = gamma.diff(t)
print("γ'(t) =", velocity.T)

# 速率 = 速度向量的範數
speed = sp.sqrt(velocity.dot(velocity))
print("||γ'(t)|| =", sp.simplify(speed))

輸出:

γ'(t) = Matrix([[-a*sin(t), a*cos(t), b]])
||γ'(t)|| = sqrt(a**2 + b**2)

螺旋線的速率是常數 \(\sqrt{a^2+b^2}\) ——它以等速上升又等速旋轉,所以整體等速。

計算一段弧長#

# 從 t=0 到 t=2*pi 的弧長
L = sp.integrate(sp.sqrt(velocity.dot(velocity)), (t, 0, 2*sp.pi))
print(L)   # 2*sqrt(a**2 + b**2)*pi

以弧長重新參數化(可瑞士刀式操作)#

# 弧長函數 s(t)
s = sp.Function('s')

s_of_t = sp.integrate(sp.sqrt(velocity.dot(velocity)), (t, 0, t))
print("s(t) =", s_of_t)   # sqrt(a**2 + b**2)*t

# 反解 t(此處是線性關係,可以反解)
t_of_s = sp.solve(sp.Eq(s_of_t, sp.Symbol('s')), t)[0]
Gamma = gamma.subs(t, t_of_s)
print("γ(s) =", Gamma.T)
# 檢驗:||dΓ/ds|| 應為 1
Gamma_s = Gamma.diff(sp.Symbol('s'))
print(sp.simplify(sp.sqrt(Gamma_s.dot(Gamma_s))))   # 1

這裡螺旋線的 \(s(t)=\sqrt{a^2+b^2}\,t\) 是線性函數,反解容易。但對像擺線這類曲線,solve 會失敗或給出隱式解——這是正常的,也是後面「一般參數公式」存在的理由。

動手實驗#

實驗 1:圓的弧長

import sympy as sp
t = sp.symbols('t', real=True)
r = sp.symbols('r', positive=True)

circle = sp.Matrix([r*sp.cos(t), r*sp.sin(t), 0])
v = circle.diff(t)
L = sp.integrate(sp.sqrt(v.dot(v)), (t, 0, 2*sp.pi))
print(L)      # 應得 2*pi*r

改變積分上限到 \(T\) ,確認弧長為 \(rT\) ;再改參數化為 \((r\cos 2t, r\sin 2t, 0)\) ,跑同一行程式——弧長不變,驗證「弧長是幾何量」。

實驗 2:螺旋線的弧長與「每圈爬升」

a, b = sp.symbols('a b', positive=True)
gamma = sp.Matrix([a*sp.cos(t), a*sp.sin(t), b*t])
v = gamma.diff(t)
L1 = sp.integrate(sp.sqrt(v.dot(v)), (t, 0, 2*sp.pi))
print("一圈弧長:", sp.simplify(L1))          # 2*pi*sqrt(a**2+b**2)
print("一圈爬升高度:", gamma.subs(t, 2*sp.pi)[2] - gamma.subs(t, 0)[2])  # 2*pi*b
# 幾何直覺:一圈弧長^2 = (圓周部分)^2 + (爬升部分)^2 ?用勾股定理檢驗:
print(sp.simplify(L1**2 - ((2*sp.pi*a)**2 + (2*sp.pi*b)**2)))   # 應為 0

實驗 3:橢圓弧長沒有初等封閉形式

A, B = sp.symbols('A B', positive=True)
ellipse = sp.Matrix([A*sp.cos(t), B*sp.sin(t), 0])
v = ellipse.diff(t)
sp.integrate(sp.sqrt(v.dot(v)), (t, 0, 2*sp.pi))

你會發現 SymPy 無法給出封閉形式(結果涉及橢圓積分 elliptic_e)。這不是 SymPy 不夠強——數學上就是沒有初等反導數。可改用數值:sp.integrate(...).evalf()。

實驗 4(挑戰):擺線的弧長反而有封閉形式

擺線 \(\gamma(t) = (t - \sin t,\ 1 - \cos t,\ 0)\) ,計算 \(t\in[0, 2\pi]\) 的弧長,你應得到 \(8\) (半徑為 1 的滾圓)。試著解釋為什麼速度會在 \(t=0\) 處變成零、這對「以弧長反解 \(t\) 」造成什麼麻煩。

小結與練習#

本節重點

  1. 參數曲線是「幾何路徑 + 走法」,同一曲線可有許多參數化。
  2. \(\gamma'(t)\) 是速度向量:方向為切線、大小為速率。
  3. 弧長 \(s=\int\|\gamma'\|\,dt\) 是參數化不變量。
  4. 等速參數化( \(\|\gamma'\|\equiv 1\) )讓幾何公式最簡潔,但常無法初等反解。
  5. SymPy 三件套:Matrix 表示曲線、diff 求速度、integrate 積弧長。

練習

  1. 用 SymPy 計算曲線 \(\gamma(t) = (t, t^2, \tfrac{2}{3}t^{3/2})\) 在 \([0,1]\) 上的弧長。(提示:根號內會是完全平方,先 sp.simplify 再積分。)
  2. 將圓 \(\gamma(t) = (\cos t, \sin t)\) 以弧長參數化,寫出 \(\Gamma(s)\) 並用 SymPy 驗證 \(\|\Gamma'(s)\|=1\) 。
  3. 證明(或用 SymPy 符號驗證):若 \(\varphi\) 是可微的嚴格遞增函數,則 \(\gamma(t)\) 與 \(\tilde\gamma(u) = \gamma(\varphi(u))\) 的總弧長相同。
  4. 求一個 \(b\) 值使螺旋線 \(\gamma(t)=(\cos t, \sin t, bt)\) 一圈的弧長恰等於 \(4\pi\) 。
  5. 實驗:對「實驗 4」的擺線畫出速率函數 \(\|\gamma'(t)\|\) 隨 \(t\) 的圖形(可用 sp.plot),觀察它在哪些點為零,並討論這對弧長參數化意味著什麼。