struct PNT3D { double x, y, z; };
struct FRAME { PNT3D O, OX, OY, OZ; }; // 原點 + 三基矢量
點 p 定義於世界座標系 (WC)。欲轉入 frame:
// 1. 平移至 frame 原點
PNT3D p1 = p - frame.O;
// 2. 投影至三基矢量 (點積)
PNT3D p2;
p2.x = p1 * frame.OX; // (p - O) · OX
p2.y = p1 * frame.OY;
p2.z = p1 * frame.OZ;
p2 即為 p 在 frame 中的局部座標。
// 1. 線性組合三基矢量
PNT3D p1 = p.x * frame.OX + p.y * frame.OY + p.z * frame.OZ;
// 2. 加回原點位移
PNT3D p2 = p1 + frame.O;

mat[0] = OX.x; mat[1] = OY.x; mat[2] = OZ.x; mat[3] = O.x;
mat[4] = OX.y; mat[5] = OY.y; mat[6] = OZ.y; mat[7] = O.y;
mat[8] = OX.z; mat[9] = OY.z; mat[10] = OZ.z; mat[11] = O.z;
mat[12] = 0; mat[13] = 0; mat[14] = 0; mat[15] = 1;
驗證:[x y z 1] * M_L2W = [x*OX + y*OY + z*OZ + O, 1] ✓
mat[0] = OX.x; mat[1] = OX.y; mat[2] = OX.z;
mat[3] = -(O.x*OX.x + O.y*OX.y + O.z*OX.z);
mat[4] = OY.x; mat[5] = OY.y; mat[6] = OY.z;
mat[7] = -(O.x*OY.x + O.y*OY.y + O.z*OY.z);
mat[8] = OZ.x; mat[9] = OZ.y; mat[10] = OZ.z;
mat[11] = -(O.x*OZ.x + O.y*OZ.y + O.z*OZ.z);
mat[12] = 0; mat[13] = 0; mat[14] = 0; mat[15] = 1;
推導關鍵:(p - O) · OX = p·OX - O·OX,故平移分量為 -O·OX 等。
x = M[0][0]*Px + M[0][1]*Py + M[0][2]*Pz + M[0][3];
y = M[1][0]*Px + M[1][1]*Py + M[1][2]*Pz + M[1][3];
z = M[2][0]*Px + M[2][1]*Py + M[2][2]*Pz + M[2][3];
參數方程:P(u) = [x(u), y(u), z(u)] 或 P(u,v) = [x(u,v), y(u,v), z(u,v)]

變換後:P'(u) = M * P(u),逐分量套用矩陣乘法,得到新參數方程 [F1x(u), F1y(u), F1z(u)]。
範例:球面 x²+y²+z²-R²=0

策略:
x=u, y=v → z = ±√(R²-u²-v²)u,v 回隱式形式 (代數運算極繁瑣)範例:F(x,y,z) = x⁵+y⁵+z⁵-1=0 (高次多項式)

替代方案:
x=u, y=v 代入,用 **牛頓法/泰勒展開** 求 z 級數近似F(x,y,z)=0 求光線交點 (Sphere Tracing / Marching Cubes)
需要變換幾何物件
│
├─ 參數方程 (曲線/曲面) → 直接套用矩陣 → 完成
│
├─ 隱式方程可解析求參數 → 求參數 → 套用矩陣 → (選擇性) 消參數 → 完成
│
└─ 隱式方程不可解析求參數
├─ 精確解析式需求 → 符號運算 (Mathematica/Maple) 或放棄
├─ 即時渲染需求 → SDF / Ray Marching / Marching Cubes (GPU)
└─ 離線處理/工程近似 → 數值求解 + 參數化 → 套用矩陣