跳轉到

相機幾何與投影

檢視與投影矩陣

場景中的 3D 點先以世界座標表示。寫成齊次座標 \(p_h = (x, y, z, 1)^T\) 後,依序套用檢視矩陣 \(V\) 與投影矩陣 \(P\):\(c = P V p_h\)。透視除法得到 \(n = (c_x / c_w, c_y / c_w, c_z / c_w)\),再映射到寬 \(W\)、高 \(H\) 的畫布:

\[ x_{\text{px}} = (n_x + 1) W / 2, \quad y_{\text{px}} = (1 - n_y) H / 2. \]

縱座標的反號讓 SVG 與點陣輸出都採左上原點。

可見範圍與深度排序

檢視座標中的深度為 \(d = -z_{\text{view}}\),只有位於 near 與 far 之間的幾何會留下。繪圖元素(圖元)由遠到近穩定排序,相同深度保留場景順序。

法向量與著色

三角形法向量為 \(n = (p_1 - p_0) \times (p_2 - p_0)\)。面積為零的三角形會移除;只顯示正面的表面以 \(n \cdot v\) 判斷背面;漫反射與鏡面項在輸出前逐面計算。

Camera3D(
    *,
    id='camera',
    opacity=1.0,
    z=0.0,
    visible=True,
    semantics=None,
    position=Vec3(x=5.0, y=-7.0, z=4.0),
    target=Vec3(x=0.0, y=0.0, z=0.0),
    up=Vec3(x=0.0, y=0.0, z=1.0),
    projection='perspective',
    fov=0.6981317007977318,
    ortho_height=6.0,
    near=0.1,
    far=1000.0,
)

為透視或正交輸出建立檢視矩陣與投影矩陣。

Surface3D(
    *,
    id,
    opacity=1.0,
    z=0.0,
    visible=True,
    semantics=None,
    color=...,
    material=...,
    edge_color=None,
    edge_width=0.5,
    two_sided=True,
    grid=...,
    colorscale=None,
    value_range=None,
)

保存規則高度場,並把網格單元轉成順序一致的投影面。

Mesh3D(
    *,
    id,
    opacity=1.0,
    z=0.0,
    visible=True,
    semantics=None,
    color=...,
    material=...,
    edge_color=None,
    edge_width=0.5,
    two_sided=True,
    mesh=...,
)

保存索引式 3D 幾何;輸出前會裁切、背面剔除、著色並依深度排序各個面。

輸出格式的一致性

因此 由 KineticKit 向量繪圖端投影並排序深度的 3D 曲面 在動態 SVG、代表 PNG 與 GIF 影格中的幾何一致。

留言