
2026/01/30 7:34
**曲線物を切り分ける(数式で)**
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
改訂済み概要
本文では、複雑な3D CADジオメトリがGPUで描画できる形に変換されるプロセスを説明しています。すべての形状は三角形に分割(テッセレーション)され、頂点配列とインデックス配列として保存されます。
-
一般的なアプローチ – すべてのモデルが
に変換されるため、GPUパイプライン、STLエクスポーター、および物理エンジンに対応します。TriangleMesh { vertices, indices } -
円柱 – 無限精度で定義された
をパラメータ空間(u, v)上の格子点でサンプリングします。高さ制限は、境界頂点を円柱軸に投影して得られます(point_on_cylinder(u,v)
)。格子はセルごとに2つの三角形を生成し、サンプル数が増えるほど表面は滑らかになりますがメッシュサイズも大きくなります。典型的なセグメント数は、ほとんどのCADで32、ズーム時には64、高精度作業では128です。v = (vertex–center).dot(axis) -
平坦な面 – ファン方式で三角形分割します:1つの頂点を選び、残りのすべてのペアに接続します。n-辺多角形は n–2 個の三角形になります。
-
球体 – 緯度/経度でサンプリングします。極では全UVサンプルが1点に収束するため、アルゴリズムは四角形の代わりにファン状の三角形を発生させ、歪んだスライサーを回避します。
-
穴付き面 – 直接ファン三角分割できません。アルゴリズムは「橋を切る」ことで、右端の穴頂点と最も近い外側境界点を結び、ループを1つのポリゴンに統合した後、ファン方式を適用します。
-
非凸多角形 – 耳切り法で処理します:耳(中間頂点が凸で、他の頂点が内部に入らない連続3頂点)を特定し、それを三角形として切り出していきます。凸性と包含判定は外積と点‑内三角形テストを使用します。
-
結果 – テッセレーターは数学的に定義された曲面を、GPUが滑らかに見えるオブジェクトを効率的に描画できる密集した平坦な三角形に変換し、データサイズを管理可能に保ちます。
本文
GPUは円柱を「何か」として認識しません―三角形しか知りません。
つまり、三点とおそらく色だけです。グラフィックスハードウェアの語彙全体が一枚のインデックスカードに収まるわけです。
12 個の三角形――それがキューブを構成するすべてです。
したがって、曲面を描画できるようになる前に、誰かがそれを三角形に切り分けなければなりません―数えきれないほど多く! そして正しく配置されなければイメージは崩れてしまいます。これがテセレーションです。
三角形だけで構成
三角形メッシュは実際には二つの配列だけです:
vertices: [x₀, y₀, z₀, x₁, y₁, z₁, x₂, y₂, z₂, ...] indices : [0, 1, 2, 0, 2, 3, ...]
頂点は空間上のポイント、インデックスはそれぞれ三角形を構成する三つのポイントを指します。これがすべてです!
あなたが今まで見た全ての 3D モデル――ゲームキャラクター、CAD レンダリング、ピクサーのフレーム――はこの二つの配列を GPU に渡し、GPU が三角形を極めて高速に描画することで実現されています。
翻訳問題
vcad のカーネルでは円柱は三角形ではありません。数式で表されます:
fn point_on_cylinder(u: f64, v: f64) -> Point3 { Point3::new( radius * u.cos(), radius * u.sin(), v, ) }
角度
u と高さ v を与えれば、正確な点を返します。無限精度!ファセットはありません。数学的には美しいですが、レンダリングには使えません。テセレーターの仕事はこの関数を十分にサンプリングして説得力あるメッシュを作ることです。
曲面のサンプリング
滑らかな曲面を三角形に変える方法?それはサンプリングです!
- パラメータ空間(平坦な
ドメイン)にグリッドを敷く。(u, v) - 各格子点で表面を評価し、3D 座標を取得。
- 隣接する点を三角形に結ぶ。
サンプル数が多ければ結果は滑らかになり、三角形も増えます――すなわち全体の処理速度は遅くなります。
円周方向に 32 段で十分とされることが多いですが、ズームインするなら 64、より高精度を求めれば 128 など。
平面面:簡単ケース
平面はすでにトポロジー上の頂点があるのでサンプリングは不要です。
凸多角形の場合は「ファン三角化」が最適です:
- 一つの頂点を選び、残りの各ペアと三角形を作る。
四辺形は 2 個、六辺形は 4 個、一般の n 辺形は
n‑2 個になります。
曲面:円柱
円柱は UV‑グリッド手法が必要です。
u パラメータは円周方向(0 → 2π)、v は上下方向です。表面式が無限に広がるため、停止点を決めなければなりません。答えは境界辺を見て、それらを円柱軸上に射影して高さ範囲を求めることです。
for vertex in boundary { let v = (vertex - center).dot(axis); v_min = v_min.min(v); v_max = v_max.max(v); }
これで
v_min から v_max、円周全体にわたるグリッドをサンプリングします。各セルは二つの三角形になります。
曲面:球
同じ考え方ですが、緯度/経度で UV を設定します。ただし極点に注意が必要です:
- 極点付近では UV の上行列全てが同一点へマップされます。
- 北極・南極では一連のサンプルが単一点に崩壊します。
- 四角形を作ろうとすると退化したスライサーになります!
対策: 極点では四角形ではなく三角形を出力します。極頂点は全ての三角形の共通頂点となり、オレンジのセグメントが茎に集まるような構造です。
難しいケース:穴付き面
上記は単純面(外周のみ)を想定しています。
板に穴を開けた場合?内側のループが存在します。ファン三角化では穴が埋められてしまいます!
トリック: 機能的ブリッジを作る。
- 穴の右端点を見つけ、外周上で最も近い点と二つの辺(そこへ行き戻り)で結びます。
- これにより両ループが一つの連続した多角形になります。
耳切りアルゴリズム
合成された多角形は凸ではありませんので、ファン三角化は使えません。実際のアルゴリズムを適用します:
- 非凸多角形:耳(エア) を探す。
- 三つ連続した頂点で、中間が凸(外向き)かどうか。
- 他にその三角形内に入る頂点がないか。
それを三角形として切り離し、繰り返します。最後に残った三角形だけが完成です。これはピザを外側から食べていくようなイメージです。
- 凸判定:線分のどちら側に頂点があるかで判断。
- 内包判定:点がその三角形の全ての辺に囲まれているか確認。
これらは数回の乗算だけで済み、リアルタイムでも十分です。
出力
すべての曲面(平面・円柱・球・円錐・穴付き面)を最終的に次の形に変換します:
TriangleMesh { vertices: Vec<f32>, // [x, y, z, x, y, z, ...] indices : Vec<u32>, // [i, j, k, i, j, k, ...] }
GPU が欲しがる形式、STL ファイルで使われる形式、物理エンジンが期待する形式です。
テセレーターは CAD の世界における最終ステップであり、幾何学を現実の世界へと導く役割を果たします。
イリュージョン
覚えておいてください:GPU は「球」を知りません。
あなたが見ているものは滑らかな球です。
スクリーン上に映る全ての滑らかな曲面は、実際には極めて細かい平面三角形で構成されており、人間の目では区別できないほど密集しています。それが「トリック」―そして全てのトリックです。
テセレーターはマジシャンの助手。美しい数学的曲線を取り込み、静かに、見えずに GPU が描ける何かへと切り分けます。
画面上で回転するその滑らかな球を眺めた時、その背後には数多くの三角形が潜んでいることは、あなたにはわからないでしょう。