相机几何与投影
查看与投影矩阵
场景中的 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 帧中的几何一致。