還記得在第4單元第6課(如4-6c 滾動軌跡(餘弦函數)) 我們學過2D平面動畫,透過某個點或線的運動軌跡,可以畫出有趣的曲線與圖案,例如擺線、函數曲線、心臟線等。

RealityKit 擠出成型過程類似,差別只不過是從2D平面拓展到3D空間,原本是一個點或線在平面的運動軌跡,拓展成一個面在空間中的運動軌跡。
不管是2D平面或是3D空間,物體的運動(位移、旋轉)與變形(縮放、鏡像)都可以用座標變換來控制。上一節的空心管就是如此,母版是一個XY平面的同心圓,經由Z軸平移的運動軌跡(記錄在「變換矩陣陣列」中),就得到一個空心管3D模型。
本節要製作的甜甜圈仍依循此程序,先做一個XY平面的圓(假設半徑=0.5),令圓心離開座標原點一段距離(例如 [1, 0]),接著讓整個圓繞Y軸轉一圈(半徑=1),就會得到一個立體的環面(Torus),也就是甜甜圈。
我們曾在6-1b SceneKit內建的幾何模型 介紹過 SceneKit 內建的甜甜圈模型,甜甜圈的內徑(ring radius)是繞行路徑的半徑,外徑(pipe radius)則是橫截面的圓半徑,兩者相加,才是甜甜圈(中心點到最外側)的半徑。下圖取自SCNTorus說明文件:

簡單地說,環面(甜甜圈)就是一個小圓(以圓心)在空間中繞另一個大圓所形成,這兩個圓(的平面)彼此垂直。
本節母版形狀是一個圓,直接用 SwiftUI 的 Circle() 即可。唯一需要計算的是母版小圓所在的外框位置,外框原點在空間座標系統中是位於左下角(若是在 SwiftUI 或 Canvas 的螢幕座標系統,原點在左上角):

根據上圖,設定外框的程式碼如下:
// 外框原點在左下角(空間座標)
let 外框 = CGRect(x: r1 - r2, y: -r2, width: r2*2.0, height: r2*2.0)
let 形狀 = Circle().path(in: 外框)
這次我們將「MeshResource.製作甜甜圈()」做成共享程式,請將以下程式碼放在共享區: