跳轉到

02.2 高斯曲率與平均曲率#

本節目標#

  • 從法曲率的幾何直覺出發,導出主曲率、高斯曲率 \(K\) 與平均曲率 \(H\) 。
  • 熟悉經典結果:球面 \(K = 1/R^2\) 、柱面 \(K = 0\) 、馬鞍面 \(K < 0\) 。
  • 用 SymPy 程式化「第一基本形式 + 第二基本形式 \(\Rightarrow K, H\) 」的教科書流程。
  • 體會極小曲面( \(H = 0\) ,肥皂膜)為什麼迷人。

幾何直覺:曲面在每一點有多「彎」?#

把曲面想成一張被彎曲的薄膜。固定點 \(P\) 上,取一個法向量 \(\mathbf{n}\) ,任何一個 切方向 \(\mathbf{w}\) 決定一個「截平面」;曲面被這個平面切出的曲線在 \(P\) 附近的 曲率叫做法曲率 \(\kappa_n(\mathbf{w})\) 。規定凸向外時為正,則:

  • 球面:每個方向都同樣彎, \(\kappa_n\) 全相同。
  • 馬鞍面:有些方向往上彎(正),有些往下彎(負)。

法曲率隨方向轉動時必須取到極大與極小各一次(Euler 定理),這兩個方向互相 垂直,對應的值 \(\kappa_1 \ge \kappa_2\) 稱為主曲率。由它們組合出兩個最重要的 純量:

\[ K = \kappa_1 \kappa_2 \quad (\text{高斯曲率}), \qquad H = \frac{\kappa_1 + \kappa_2}{2} \quad (\text{平均曲率}). \]

用幾個經典例子校準直覺:

曲面 \(\kappa_1\) \(\kappa_2\) \(K\) \(H\) 直覺
半徑 \(R\) 球面 \(1/R\) \(1/R\) \(1/R^2 > 0\) \(1/R\) 全方向同向彎
柱面 \(1/R\) \(0\) \(0\) \(1/(2R)\) 沿軸方向是直線
馬鞍 \(z = xy\) \(+\) \(-\) \(< 0\) 可為 0 兩主方向異號
平面 \(0\) \(0\) \(0\) \(0\) 根本不彎

\(K\) 的符號立刻分類三種幾何: \(K>0\) 局部像球(三角形內角和 \(>180^\circ\) )、 \(K<0\) 局部像馬鞍( \(<180^\circ\) )、 \(K=0\) 局部像平面( \(=180^\circ\) )。

計算流程:第一 + 第二基本形式#

教科書公式如下。設 \(E,F,G\) 如前節,法向量

\[ \mathbf{n} = \frac{\mathbf{r}_u \times \mathbf{r}_v}{\|\mathbf{r}_u \times \mathbf{r}_v\|}, \]

第二基本形式的係數是

\[ L = \mathbf{r}_{uu} \cdot \mathbf{n}, \qquad M = \mathbf{r}_{uv} \cdot \mathbf{n}, \qquad N = \mathbf{r}_{vv} \cdot \mathbf{n}. \]

則

\[ K = \frac{LN - M^2}{EG - F^2}, \qquad H = \frac{EN - 2FM + GL}{2(EG - F^2)}. \]

把它全部寫成 SymPy 函式:

import sympy as sp

u, v, R, a, b = sp.symbols('u v R a b', positive=True)

def curvatures(r, P=u, Q=v):
    """回傳 (K, H);r 為參數曲面分量 list,P, Q 為其參數符號。"""
    ru  = [sp.diff(c, P) for c in r]
    rv  = [sp.diff(c, Q) for c in r]
    ruu = [sp.diff(c, P, 2) for c in r]
    ruv = [sp.diff(c, P, Q) for c in r]
    rvv = [sp.diff(c, Q, 2) for c in r]
    cross = lambda p, q: [p[1]*q[2]-p[2]*q[1],
                          p[2]*q[0]-p[0]*q[2],
                          p[0]*q[1]-p[1]*q[0]]
    dot   = lambda p, q: sum(pi*qi for pi, qi in zip(p, q))
    nv = cross(ru, rv)
    nn = [sp.simplify(c / sp.sqrt(dot(nv, nv))) for c in nv]
    E, F, G = (sp.simplify(dot(ru, ru)), sp.simplify(dot(ru, rv)),
               sp.simplify(dot(rv, rv)))
    Lc, Mc, Nc = (sp.simplify(dot(ruu, nn)), sp.simplify(dot(ruv, nn)),
                  sp.simplify(dot(rvv, nn)))
    K = sp.simplify(sp.cancel((Lc*Nc - Mc**2) / (E*G - F**2)))
    H = sp.simplify(sp.cancel((E*Nc - 2*F*Mc + G*Lc) / (2*(E*G - F**2))))
    return K, H

# --- 球面:theta 為餘緯,相當於「v 參數」---
theta = sp.symbols('theta', real=True)
sphere = [R*sp.sin(theta)*sp.cos(u), R*sp.sin(theta)*sp.sin(u), R*sp.cos(theta)]
Ks, Hs = curvatures(sphere, u, theta)
# 除極點外 sin(theta) > 0,可把 simplify 產生的 Abs 拿掉
print(sp.simplify(Ks))                                  # 1/R**2
print(Hs.subs(sp.Abs(sp.sin(theta)), sp.sin(theta)))    # 1/R

# --- 柱面 ---
cyl = [R*sp.cos(u), R*sp.sin(u), v]
print(curvatures(cyl))      # (0, 1/(2*R))

# --- 馬鞍面 z = x*y,參數化 (u, v, u*v) ---
sad = [u, v, u*v]
print(curvatures(sad))      # (-1/(u**2 + v**2 + 1)**2, -u*v/(u**2 + v**2 + 1)**(3/2))

三個結果完全符合直覺表:球 \(K = 1/R^2\) ,柱 \(K = 0\) (雖然 \(H \ne 0\) ),馬鞍 \(K = -1/(1+u^2+v^2)^2 < 0\) 。注意 \(z=xy\) 的平均曲率 \(H = -uv/(1+u^2+v^2)^{3/2}\) 只在兩條軸線上為 0,它並不是極小曲面——「 \(K<0\) 」與「 \(H=0\) 」是兩件獨立的事, 別混淆。

環面: 正負都有#

環面 \(\mathbf{r}(u,v) = ((a + b\cos v)\cos u,\; (a + b\cos v)\sin u,\; b\sin v)\) 的公式(同一批參數沿用即可):

torus = [(a + b*sp.cos(v))*sp.cos(u),
         (a + b*sp.cos(v))*sp.sin(u),
         b*sp.sin(v)]
Kt, Ht = curvatures(torus)
print(sp.simplify(Kt))   # cos(v) / (b*(a + b*cos(v)))
# 取 a > b > 0 時 a + b*cos(v) > 0,移除 Abs
print(Ht.subs(sp.Abs(a + b*sp.cos(v)), a + b*sp.cos(v)))
# (a + 2*b*cos(v)) / (2*b*(a + b*cos(v)))

高斯曲率 \(K = \dfrac{\cos v}{b(a + b\cos v)}\) :外圈( \(v\) 小, \(\cos v > 0\) )像球 \(K>0\) ;內圈( \(\cos v < 0\) )像馬鞍 \(K<0\) ;上下兩條核心圓上 \(K = 0\) 。一個環面 自帶全部三種幾何,非常適合當「檢驗直覺的教具」。

畫圖:K 沿環面的分布#

import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(12, 5))
A, B = 3.0, 1.0
U, V = np.meshgrid(np.linspace(0, 2*np.pi, 80), np.linspace(0, 2*np.pi, 80), indexing='ij')
X, Y, Z = (A + B*np.cos(V))*np.cos(U), (A + B*np.cos(V))*np.sin(U), B*np.sin(V)
Kt = np.cos(V) / (B*(A + B*np.cos(V)))

ax1 = fig.add_subplot(121, projection='3d')
ax1.plot_surface(X, Y, Z, facecolors=plt.cm.coolwarm(
    (Kt - Kt.min())/ (Kt.max() - Kt.min())), rstride=1, cstride=1)
ax1.set_title('torus colored by Gaussian curvature')

ax2 = fig.add_subplot(122)
im = ax2.pcolormesh(U, V, Kt, cmap='coolwarm', shading='auto')
ax2.set_xlabel('u'); ax2.set_ylabel('v')
ax2.set_title('K(u,v), red = K>0 (outer), blue = K<0 (inner)')
plt.colorbar(im, ax=ax2)
plt.tight_layout(); plt.show()

右圖清楚顯示 \(K\) 只依賴 \(v\) :外圈紅(正)、內圈藍(負)、中線白(零)。

動手實驗:極小曲面與肥皂膜#

把鐵絲框浸肥皂水,膜會收縮成極小曲面:每一點平均曲率 \(H = 0\) (表面張力 想最小化面積)。驗證兩個經典例子:

c = sp.symbols('c', positive=True)
helicoid = [u*sp.cos(v), u*sp.sin(v), c*v]
Kh, Hh = curvatures(helicoid)
print(sp.simplify(Hh))   # 0  → 螺旋面是極小曲面!
print(sp.simplify(Kh))   # -c**2/(c**2 + u**2)**2 < 0

# 懸鏈面 (catenoid):cosh 鏈繞 z 軸旋轉
w = sp.symbols('w', real=True)
cat2 = [sp.cosh(w)*sp.cos(u), sp.cosh(w)*sp.sin(u), w]
Kc, Hc = curvatures(cat2, u, w)
print(sp.simplify(Hc))   # 0
print(sp.simplify(Kc))   # -sech(w)**4:與 u 無關的負值,和螺旋面等距(見 02.3)

兩個曲面都 \(H=0\) 、 \(K<0\) 。事實上螺旋面與懸鏈面之間存在一個等距變換 (可以互相彎過去而不伸縮)——這是 02.3 要講的主題的漂亮例子。

再畫出螺旋面看看:

import numpy as np, matplotlib.pyplot as plt
uu, vv = np.meshgrid(np.linspace(-2, 2, 40), np.linspace(0, 3*np.pi, 90), indexing='ij')
fig = plt.figure(figsize=(6, 5))
ax = fig.add_subplot(projection='3d')
ax.plot_surface(uu*np.cos(vv), uu*np.sin(vv), vv, cmap='viridis', alpha=0.8)
ax.set_title('helicoid (minimal surface, H=0)')
plt.show()

小結與練習#

  • 法曲率極值給主曲率 \(\kappa_1, \kappa_2\) ; \(K = \kappa_1\kappa_2\) 衡量「配合 幾何類型」, \(H = (\kappa_1+\kappa_2)/2\) 衡量「彎的總量」。
  • 計算配方: \(\mathbf{r}(u,v) \to\) 一階/二階導 \(\to E,F,G\) 與 \(L,M,N \to K, H\) 。
  • 球 \(K>0\) 、柱 \(K=0\) 、鞍 \(K<0\) ;環面三種都有; \(H=0\) 即極小曲面(肥皂膜)。

練習:

  1. 計算球面 \(K\) 與 \(H\) 皆為常數,驗證 \(H^2 - K = \kappa_1\kappa_2\) 關係式在球面上給出什麼。
  2. 用 curvatures 處理拋物面 \(z = x^2 + y^2\) ,確認 \(K > 0\) 處處。
  3. 證明(或用 SymPy 驗證)柱面 \(H = 1/(2R)\) 但 \(K = 0\) :兩主曲率一為 \(1/R\) 一為 \(0\) 。
  4. 找出環面上 \(K = 0\) 的兩個圓參數值,並在 3D 圖上把這兩條「視差線」畫出來。
  5. 偽球面(pseudosphere) \(\mathbf{r}(u,v) = (a\cos u \sin v,\; a\sin u\sin v,\; a(\cos v + \ln\tan(v/2)))\) , 嘗試算出 \(K = -1/a^2\) (計算較長,可用 sp.trigsimp)。