※小説ではない※専門書 要約資料集 為替(換算)3.9万円でもらう 紐解集生成 専門 初入門 資料   作:{作者名}

270 / 382
# BOOK-0226 情報派生_3DCG幾何学の実装数学 — クリックの先にある世界へ(第1巻)

> 学問の宇宙・応用の軌道ステーション群(情報工学)派生章・情報・計算冠。ガイド役: Fable 5 監修 / Sonnet 5 執筆(脚本班)
> トーン規約: GAKUMON_UNIVERSE.md準拠。専門用語は初出で必ず説明する。水準五〜八中心。
> 前提知識: →BOOK-0071(数学派生_線形代数_第1巻、水準一〜四)の第一章(ベクトル)・第三章(行列)・第四章(行列式`ad-bc`と固有値の入口)を読み終えていることが望ましい。より進んだ話題(対角化・スペクトル定理)を扱う→BOOK-0120(数学派生_線形代数_第2巻、水準五〜六)は必須の前提ではないが、本書第三章で一度だけ接続する。
> 直接の前巻: →BOOK-0187(額縁から景色へ_射影の数式と3DCG構造史、水準四〜八)。BOOK-0187は「カメラ座標→スクリーン座標」という片道の射影数学を、針穴カメラから透視射影行列・ビューイングパイプライン・ラスタライズまで一本道でたどった。本書はその逆方向(スクリーン座標→ワールド座標、すなわちマウスのクリックが3D空間のどの点を指したかを求める「ピッキング」)と、3DCG実装の現場で必須になる周辺の数学的道具一式(外積・クォータニオン・逆行列による法線変換・ジオメトリの手続き的生成とシェーダ)を扱う。BOOK-0187が「額縁の外から中を見る」旅だったとすれば、本書は「額縁の中から、もう一度外の世界へ手を伸ばす」旅である。
> 誠実な立場の明記: 本書はgakumon(理論・書籍側)の資料に存在した構造的な穴——3D幾何学ドメインの欠落——を埋めるために執筆された(CLAUDE.md「ギャップ駆動辞書拡充規約」GAP-0006〜0010に対応)。FUNC辞書(コード生成カード側)に同種の穴が残っている場合、それは別レーンの管轄であり本書の範囲外であることを、終章で明記する。

---


# BOOK-0226 情報派生_3DCG幾何学の実装数学 — クリックの先にある世界へ(第1巻)

# BOOK-0226 情報派生_3DCG幾何学の実装数学 — クリックの先にある世界へ(第1巻)

 

> 学問の宇宙・応用の軌道ステーション群(情報工学)派生章・情報・計算冠。ガイド役: Fable 5 監修 / Sonnet 5 執筆(脚本班)

> トーン規約: GAKUMON_UNIVERSE.md準拠。専門用語は初出で必ず説明する。水準五〜八中心。

> 前提知識: →BOOK-0071(数学派生_線形代数_第1巻、水準一〜四)の第一章(ベクトル)・第三章(行列)・第四章(行列式`ad-bc`と固有値の入口)を読み終えていることが望ましい。より進んだ話題(対角化・スペクトル定理)を扱う→BOOK-0120(数学派生_線形代数_第2巻、水準五〜六)は必須の前提ではないが、本書第三章で一度だけ接続する。

> 直接の前巻: →BOOK-0187(額縁から景色へ_射影の数式と3DCG構造史、水準四〜八)。BOOK-0187は「カメラ座標→スクリーン座標」という片道の射影数学を、針穴カメラから透視射影行列・ビューイングパイプライン・ラスタライズまで一本道でたどった。本書はその逆方向(スクリーン座標→ワールド座標、すなわちマウスのクリックが3D空間のどの点を指したかを求める「ピッキング」)と、3DCG実装の現場で必須になる周辺の数学的道具一式(外積・クォータニオン・逆行列による法線変換・ジオメトリの手続き的生成とシェーダ)を扱う。BOOK-0187が「額縁の外から中を見る」旅だったとすれば、本書は「額縁の中から、もう一度外の世界へ手を伸ばす」旅である。

> 誠実な立場の明記: 本書はgakumon(理論・書籍側)の資料に存在した構造的な穴——3D幾何学ドメインの欠落——を埋めるために執筆された(CLAUDE.md「ギャップ駆動辞書拡充規約」GAP-0006〜0010に対応)。FUNC辞書(コード生成カード側)に同種の穴が残っている場合、それは別レーンの管轄であり本書の範囲外であることを、終章で明記する。

 

---

 

## 一枚要約(本書の地図)

 

**目的**: BOOK-0187が扱わなかった「スクリーン座標からワールド座標へ戻る」逆方向の変換(ピッキング)を主軸に据え、そのために必要となる3DCG実装の道具一式——外積・クォータニオン・逆行列と法線変換・ジオメトリ生成——を、検算つきでそろえること。

 

**得られる力**: 本書を読み終えると、マウスのクリック位置から3D空間のどの物体を選んだかを計算で求める手順、2つのベクトルから面の法線を求める外積の使い方、ジンバルロックを起こさずに3D回転を扱うクォータニオンの仕組み、モデルを非一様に拡大縮小しても法線が壊れない逆転置行列の理屈、そして立方体や球の頂点データをどう生成しGLSLシェーダへ渡すか、という一連の流れを自分の言葉で説明できるようになる。

 

**再利用可能性**: 本書で確立する外積・クォータニオン・逆行列・レイキャストの基礎は、ゲームEditor本体の3Dプレビュー機能、原画班が扱う手続き的なジオメトリ生成、演出班が扱う光影計算など、今後の3DCG関連実装全体の共通言語として再利用される想定である。またFUNC辞書側(コード生成カード)が将来3D/物理演算ドメインを新設する際の理論的出典としても参照できる。

 

**目次**: 第一章 外積/第二章 クォータニオン/第三章 逆行列と法線変換/第四章 レイキャスト・ピッキング/第五章 ジオメトリ生成の基礎/終章/章末簡易階段図/参照文献。

 

---

 

## 前提知識マップ — 4冊の関係(系統ではなく橋渡しの位置づけ)

 

本書は→BOOK-0187のような「一つの系統(造形工学系統)の第N巻」ではなく、数学冠(BOOK-0071・BOOK-0120)と造形工学系統(BOOK-0187)という異なる系統をまたいで橋渡しする、情報・計算冠の派生巻である。そのため以下は正式な「系統水準表」ではなく、読者が迷わないための前提知識マップとして示す。

 

```

┌──────────────────────────────────────────────────────────────────────┐

│ BOOK-0226 前提知識マップ(4冊の関係・水準一 ──────────→ 水準八) │

├──────────────────────────────────────────────────────────────────────┤

│ BOOK-0071 数学派生_線形代数_第1巻(水準一〜四) │

│ ベクトル・行列・行列式ad-bc・固有値の入口 │

│ ─●●●●─────────────────────────────────── │

│ │

│ BOOK-0120 数学派生_線形代数_第2巻(水準五〜六) │

│ 対角化・スペクトル定理・逆行列の記号P⁻¹が初登場(計算法は未解説) │

│ ─────●●────────────────────────────────── │

│ │

│ BOOK-0187 額縁から景色へ_射影の数式と3DCG構造史(水準四〜八) │

│ カメラ座標→スクリーン座標(片道)・同次座標・ビューイングパイプライン │

│ ───●●●●●●●●───────────────────────── │

│ │

│ BOOK-0226 本書(水準五〜八) │

│ 外積・クォータニオン・逆行列と法線変換・レイキャスト(逆方向)・ │

│ ジオメトリ生成とシェーダ │

│ ─────●●●●●●●●─────────────────────── │

└──────────────────────────────────────────────────────────────────────┘

```

 

BOOK-0071とBOOK-0120は「数の表をどう計算するか」という一般論を、BOOK-0187は「カメラ座標を一方向にスクリーンへ落とし込む数式」を、それぞれ担当してきた。本書はこの2つの系統が交差する地点——3DCGの実装現場で実際に手を動かすときに必要になる、しかしどちらの系統の巻にも収まりきらなかった道具一式——を担当する。

 

---

 

## 講師からの前書き — 額縁の中から、もう一度手を伸ばす

 

前巻BOOK-0187を読み終えた読者は、一つの点が、カメラという額縁を通ってスクリーンの上の一点として結像するまでの、長い計算の道のりを見届けたはずである。針穴カメラから始まり、同次座標という4成分の数の並びを経て、透視射影行列という一枚の行列が、視点(1, 2, 5)という3次元の点を、スクリーン上の(約307.2, 約153.6)という2次元のピクセル位置へと変換する様子を、具体的な数値で検算した。

 

しかし、実際に3DCGを実装する現場で最初にぶつかる問いは、しばしばその逆である。プレイヤーが画面上の(307, 154)というピクセルをマウスでクリックしたとき、3D空間に浮かぶどの物体を選んだのか——これをコンピュータはどう計算で当てるのか。BOOK-0187が固定した「カメラ→スクリーン」という一方通行の道を、逆向きに再生することはできるのか。答えは「できる」であり、本書第四章でその具体的な手順を、BOOK-0187が使った数値例そのものを逆にたどることで検算する。

 

ただし、この「逆再生」という主役級の問いにたどりつくためには、道具箱を先に整えておく必要がある。本書では、3D空間に浮かぶ一辺2の立方体を狂言回しに据え、次の一本道をたどる。まず、その立方体の面がどちらを向いているかを知るための、内積とは異なる「もう一つの掛け算」——**外積**を手に入れる(第一章)。次に、その立方体をオイラー角の落とし穴(ジンバルロック)にはまらずに回転させる道具——**クォータニオン**を手に入れる(第二章)。続いて、BOOK-0071が入口だけ示した「行列式」を使って**逆行列**を実際に計算し、立方体を歪めて拡大縮小しても面の向き(法線)が壊れないようにする補正——**逆転置行列**を手に入れる(第三章)。ここまでの道具がそろって初めて、マウスクリックから立方体を選び出す**レイキャスト・ピッキング**の計算が可能になる(第四章)。そして最後に、そもそもその立方体や球の頂点データがどう生成され、画面に描かれるまでにGLSLのシェーダコードの中で何が起きているのかを見る(第五章)。

 

数値の検算を惜しまないという約束は、BOOK-0187から変わらない。一段ずつ確実に、額縁の中から外の世界へ手を伸ばしていこう。

 

---

 

## 休憩所ゼロ: まとめ箱 — 前書きのポイント

 

```

本書の問い: BOOK-0187が固定した「カメラ→スクリーン」の一方通行を、逆向きに再生できるか

答えの骨格: スクリーン座標 → (射影行列の逆行列という道具) → ワールド座標、という復路の変換

 

旅程: 外積(面の向きを知る) → クォータニオン(立方体を回転させる)

→ 逆行列と法線変換(歪めても法線を壊さない) → レイキャスト・ピッキング(BOOK-0187を逆再生する)

→ ジオメトリ生成とシェーダ(すべての道具が実際のコードの中で再会する)

```

 

---

 

## 第一章: 外積 — もう一つの掛け算

 

### 1-1. なぜ「もう一つの掛け算」が要るのか

 

→BOOK-0071 第一章では、2つのベクトルから1つの数(スカラー)を作る**内積**(ないせき)という演算を学んだ。ベクトル`(1,2)`と`(3,1)`の内積が`1×3+2×1=5`という1つの数になったことを思い出してほしい。内積は「2本のベクトルがどれくらい同じ方向を向いているか」を測る道具である。

 

しかし3次元の世界では、これとは別の問いが頻繁に生じる。「この面はどちらを向いているか」「この2本の辺が作る平行四辺形の面積はいくらか」——これらの問いに答えるには、2つのベクトルから1つの数ではなく、**もう1つの新しいベクトル**を作り出す演算が必要になる。この演算を**外積(がいせき、cross product、水準五: 3次元空間にある2つのベクトルから、その両方に垂直な、新しい1つのベクトルを作り出す演算)**と呼ぶ。

 

内積が「2本の矢印から1つの数を作る」道具だったのに対し、外積は「2本の矢印から、それらが張る平面に突き刺さる、もう1本の矢印を作る」道具である、と言い換えられる。

 

### 1-2. 外積の定義と成分計算

 

ベクトル`a = (a₁, a₂, a₃)`とベクトル`b = (b₁, b₂, b₃)`の外積`a × b`は、次の式で計算される成分を持つ、新しいベクトルである。

 

```

a × b = (a₂b₃ - a₃b₂, a₃b₁ - a₁b₃, a₁b₂ - a₂b₁)

```

 

この式は一見複雑に見えるが、成分の並びには規則がある。x成分はyとzの組、y成分はzとxの組、z成分はxとyの組というように、添字が(y,z)→(z,x)→(x,y)と巡回していく。

 

外積が作り出す新しいベクトルには、2つの重要な性質がある。

 

- **向き**: `a × b`は、`a`にも`b`にも垂直な方向を向く(次節の**右手系**という約束事に従う)。

- **大きさ**: `a × b`の長さ(ノルム)は、`|a| × |b| × sin θ`(θは`a`と`b`のなす角)に等しく、これは`a`と`b`が作る平行四辺形の面積とちょうど一致する。

 

### 1-3. 右手系という約束事

 

`a × b`が具体的にどちら向きを指すかは、**右手系(みぎてけい、水準五: 右手の親指・人差し指・中指をそれぞれ直交させたときの向きを基準とする座標系の約束事。人差し指をaの向き、中指をbの向きに合わせたとき、親指が指す方向がa×bの向きになる)**という約束事によって決まる。あるいは、右手の指をaからbへ向かって握り込んだとき、親指が指す方向がa×bの向き、と覚えてもよい。

 

たとえば`a = (1,0,0)`(x軸方向)、`b = (0,1,0)`(y軸方向)とすると、式に代入して

 

```

a × b = (0×0 - 0×1, 0×0 - 1×0, 1×1 - 0×0) = (0, 0, 1)

```

 

となり、z軸方向を指す。これは右手の人差し指をx軸、中指をy軸に向けたとき、親指がz軸(画面の手前)を指す、という直感とちょうど一致する。

 

なお、3DCGライブラリによっては右手系ではなく**左手系**(左手の指で同じ規則を考える座標系)を採用する流儀の違いがある(たとえばOpenGL・WebGLは伝統的に右手系を基準に説明されることが多く、DirectXや一部のゲームエンジンは左手系を採用することが多いとされる)。本書では、→BOOK-0187と同様に、特に断らない限り右手系を基準として説明する。

 

### 1-4. 検算例1: 立方体の面法線を外積で求める

 

外積の最も重要な応用が、**面法線(めんほうせん、法線ベクトル、水準五: ある平面や曲面に対して垂直に立つ、向きを持つベクトル。3DCGでは光の当たり方の計算に使われる)**を求める計算である。

 

一辺2の立方体(中心が原点、各辺が座標軸に平行)を考え、その前面(z=1の面)の4つの頂点を、反時計回り(前面の外側、つまり+z方向から見て)に次のようにとる。

 

```

v0 = (-1, -1, 1)

v1 = ( 1, -1, 1)

v2 = ( 1, 1, 1)

v3 = (-1, 1, 1)

```

 

この面の法線を求めるには、面上の2本の辺ベクトルを作り、それらの外積をとればよい。

 

```

edge1 = v1 - v0 = (2, 0, 0)

edge2 = v3 - v0 = (0, 2, 0)

```

 

外積の式に代入すると、

 

```

edge1 × edge2 = (0×0 - 0×2, 0×0 - 2×0, 2×2 - 0×0) = (0, 0, 4)

```

 

この結果の長さは`√(0²+0²+4²) = 4`なので、正規化(長さ1に揃えること)すると法線は`(0, 0, 1)`となる。これは「前面(z=1の面)は+z方向を向いている」という直感と完全に一致する。

 

さらに、外積の大きさが面積を表すという性質も検算しておこう。`edge1`の長さは2、`edge2`の長さも2で、この2本は互いに垂直(内積`2×0+0×2=0`)なので、2本が張る平行四辺形は1辺2の正方形であり、その面積は`2×2=4`。外積の大きさ`|edge1 × edge2| = √(0+0+16) = 4`と、ぴったり一致する。

 

最後に、求めた法線が本当に2本の辺と垂直であることを、→BOOK-0071で学んだ**内積**を使って確認しよう。「2つのベクトルの内積が0になるとき、その2つのベクトルは直交する(垂直である)」という性質は、実装上きわめて重要な使い道である。

 

```

法線・edge1 = (0,0,1)・(2,0,0) = 0×2 + 0×0 + 1×0 = 0 (垂直、確認できた)

法線・edge2 = (0,0,1)・(0,2,0) = 0×0 + 0×2 + 1×0 = 0 (垂直、確認できた)

```

 

### 1-5. 検算例2: 軸に平行ではない一般のベクトルでの外積と、逆算チェック

 

前節の例はx・y・z軸に平行なベクトルだけを使ったため、成分の多くが0になる特殊な例だった。一般の(軸に平行でない)ベクトルでも式が正しく機能することを確かめておこう。

 

`a = (1, 2, 3)`、`b = (4, 5, 6)`とすると、

 

```

a × b = (2×6 - 3×5, 3×4 - 1×6, 1×5 - 2×4) = (12-15, 12-6, 5-8) = (-3, 6, -3)

```

 

**逆算チェック(内積による垂直性の確認)**: 求めた`a × b = (-3,6,-3)`が、本当に`a`にも`b`にも垂直かどうかを、内積で検算する。

 

```

a・(a×b) = 1×(-3) + 2×6 + 3×(-3) = -3+12-9 = 0 (垂直、一致)

b・(a×b) = 4×(-3) + 5×6 + 6×(-3) = -12+30-18 = 0 (垂直、一致)

```

 

どちらも0になり、外積の定義どおり`a`にも`b`にも垂直なベクトルが正しく求まっていることが検算できた。この「求めた外積と、元の2本のベクトルとの内積をとって0になるか確認する」という手順は、実装でバグを疑ったときに真っ先に試すべき、簡便で強力な検査法である。

 

### 深掘りコラム: 外積は「本物のベクトル」ではない?

 

やや発展的な注意点として、外積が作るベクトルは、数学的に厳密には**疑似ベクトル(ぎじべくとる、擬似ベクトル、水準八: 通常のベクトルとは異なり、鏡映変換〈左右反転〉を行うと向きが反転してしまう量)**と呼ばれる性質を持つことが知られている。たとえば鏡に映った世界でx軸だけ符号を反転させると、通常のベクトル(位置や速度など)はそのまま鏡映されるが、外積で作られるベクトル(法線や角速度など)は鏡映後に向きが反転してしまう。この性質は本書の実装レベルの話には直接影響しないため、深追いはしないが、「外積の結果は、実は少し特殊な種類の量である」という事実だけ、頭の片隅に置いておくとよい。より厳密な立場では、外積は2つのベクトルが張る平面の「向き付けられた面積」を表す、ウェッジ積(外積代数)という、より一般的な演算の3次元における特殊な現れ方だとされる。

 

---

 

## 休憩所①: まとめ箱 — 第一章のポイント

 

```

外積(a×b) = 3次元の2つのベクトルから、両方に垂直な新しいベクトルを作る演算

a×b = (a₂b₃-a₃b₂, a₃b₁-a₁b₃, a₁b₂-a₂b₁)

向き=右手系(人差し指a・中指b・親指がa×b) / 大きさ=|a||b|sinθ=平行四辺形の面積

 

内積(BOOK-0071)との対比: 内積=2ベクトル→1スカラー(似ている度合い) / 外積=2ベクトル→1ベクトル(垂直な向き)

 

検算1: 立方体前面のedge1=(2,0,0)、edge2=(0,2,0)→外積(0,0,4)→正規化で法線(0,0,1)、面積4と一致

検算2: a=(1,2,3)、b=(4,5,6)→外積(-3,6,-3)、内積によるa・(a×b)=0、b・(a×b)=0で垂直性を検算

```

 

---

 

## 第二章: クォータニオン — 回転を表すもう一つの数

 

### 2-1. オイラー角とジンバルロック問題

 

3D空間での回転を表す最も素朴な方法は、**オイラー角(おいらーかく、水準五: 回転を、X軸・Y軸・Z軸まわりの3つの角度〈たとえばロール・ピッチ・ヨー〉の組み合わせとして表す方法)**である。飛行機の姿勢を表す「ロール(横転)・ピッチ(上下)・ヨー(左右)」という言葉を聞いたことがある読者も多いだろう。これは直感的で分かりやすい表現だが、実装上、深刻な落とし穴を抱えている。

 

その落とし穴が**ジンバルロック(gimbal lock、水準六: オイラー角による回転表現において、特定の角度〈多くの場合ピッチが±90度〉になったとき、2つの回転軸が同じ向きに重なってしまい、本来3つあるはずの回転の自由度が実質2つに減ってしまう現象)**である。

 

具体例で考えてみよう。ヨー(Z軸まわり)→ピッチ(Y軸まわり)→ロール(X軸まわり)の順に回転を適用する飛行機を想像する。機体のピッチをちょうど90度(真上を向く)まで傾けると、もともと機体の前後方向を向いていたロール軸(X軸)が、世界のヨー軸(Z軸、鉛直方向)とぴったり同じ向きを向いてしまう。この状態では、ヨーを動かしてもロールを動かしても、どちらも「機体を鉛直軸のまわりでくるくる回す」という、見た目上まったく同じ結果しか生まなくなる。3つあったはずのつまみ(ヨー・ピッチ・ロール)のうち、2つが実質的に同じつまみに縮退してしまうのである。ゲームのカメラや3Dモデルの姿勢制御でオイラー角をそのまま使うと、特定の姿勢で操作が不自然にカクつく、あるいは補間(ある姿勢から別の姿勢へ滑らかに移り変わらせる処理)が破綻するという形で、この問題が表面化する。

 

### 2-2. 複素数による2次元回転の復習

 

ジンバルロックを避ける道具を導入する前に、2次元での回転を振り返っておこう。複素数`z = cosθ + i sinθ`を、ある2次元ベクトル(複素数として表現したもの)に掛けると、そのベクトルが角度θだけ回転する、という性質はよく知られている。複素数のたった1つの掛け算だけで、2次元の回転を過不足なく表現できるのである。

 

この便利な性質を3次元に拡張できないか、と考えた数学者が**ウィリアム・ローワン・ハミルトン(William Rowan Hamilton、1805年-1865年)**である。ハミルトンは複素数`a+bi`(2成分)を3成分の数の組`a+bi+cj`に拡張して3次元の回転を表そうと長年試みたが、掛け算の規則がうまく定義できず、行き詰まっていたと伝えられている。

 

### 2-3. ハミルトンの発見 — 四元数(クォータニオン)

 

1843年10月16日、ハミルトンは妻とともにダブリンの王立運河沿いを散歩していた際、3成分ではなく**4成分**の数の組を使えば、一貫した掛け算の規則が成り立つことに突然気づいたという逸話が広く伝えられている。この閃きの瞬間、ハミルトンは近くのブルーム橋(Broom Bridge)の欄干に、この発見の核心にあたる式を刻みつけたと伝えられている。

 

```

i² = j² = k² = ijk = -1

```

 

この4成分の数を**四元数(しげんすう、クォータニオン、quaternion、水準六: 1つの実数成分〈スカラー部〉と3つの虚数的な成分〈ベクトル部〉、合計4つの成分を持つ数の体系。3次元の回転を、ジンバルロックを起こさずに表現できる)**と呼ぶ。クォータニオンは通常、次のように表記される。

 

```

q = w + xi + yj + zk または q = (w, v) ただし v = (x, y, z)

```

 

wを**スカラー部**、`(x,y,z)`を**ベクトル部**と呼ぶ。

 

### 2-4. クォータニオンの積の規則(ハミルト積)

 

2つのクォータニオン`q1=(w1,x1,y1,z1)`と`q2=(w2,x2,y2,z2)`の積は、`i²=j²=k²=-1`、`ij=k, jk=i, ki=j`(この逆順`ji=-k`等は符号が反転する)という規則から導かれる、次の式で計算される。

 

```

q1 × q2 = (

w1w2 - x1x2 - y1y2 - z1z2,

w1x2 + x1w2 + y1z2 - z1y2,

w1y2 - x1z2 + y1w2 + z1x2,

w1z2 + x1y2 - y1x2 + z1w2

)

```

 

なお、クォータニオンの積の符号の取り方には、ライブラリによって流儀の違いが存在する場合がある。本書はハミルトン自身の原典に基づく`i²=j²=k²=ijk=-1`という標準的な規則を採用する。

 

→BOOK-0071 第三章では「行列の積は`AB≠BA`となる(交換法則が成り立たない)」という性質に触れた。クォータニオンの積もまったく同じ理由で非可換である——`q1×q2`と`q2×q1`は一般に異なり、回転の順序を入れ替えると結果が変わる。

 

### 2-5. 単位クォータニオンによる回転 — なぜ「半分の角度」なのか

 

ある軸(単位ベクトル`axis`)のまわりに角度θだけ回転させる操作は、次の**単位クォータニオン(たんいくぉーたにおん、水準六: 大きさがちょうど1のクォータニオン)**によって表される。

 

```

q = (cos(θ/2), sin(θ/2) × axis)

```

 

角度がθではなく**半分のθ/2**になっている点を不思議に思う読者もいるだろう。この理由は、実際にベクトルを回転させる際の計算方法にある。あるベクトル`v`を、純粋なベクトル部だけを持つクォータニオン`p=(0,v)`とみなし、次の**サンドイッチ積**によって回転後のベクトル`v'`を求める。

 

```

p' = q × p × q⁻¹

```

 

単位クォータニオンの逆元`q⁻¹`は、**共役クォータニオン(きょうやくくぉーたにおん、水準六: クォータニオン(w,x,y,z)のベクトル部の符号だけを反転させた(w,-x,-y,-z)。単位クォータニオンでは、これがそのまま逆元になる)**`(w,-x,-y,-z)`に等しい。このサンドイッチ積は、クォータニオンをvに対して2回(qを掛けて、さらにq⁻¹を掛けて)作用させる操作であるため、実際にvが回転する角度は、qが表す角度のちょうど**2倍**になる。だからこそ、θだけ回転させたいときは、その半分のθ/2をクォータニオンの角度として使う必要があるのである。

 

### 2-6. 検算: 90度回転をクォータニオンで計算する

 

ベクトル`v=(1,0,0)`を、z軸まわりに90度回転させてみよう。期待される結果は、右手系の回転により`(0,1,0)`である(→第一章1-3節で確認したx軸×y軸=z軸の関係を、逆にたどる形になる)。

 

まず回転を表す単位クォータニオンを作る。軸は`(0,0,1)`、角度はθ=90度なので、半角は45度。

 

```

q = (cos45°, sin45°×(0,0,1)) = (√2/2, 0, 0, √2/2) ≈ (0.7071, 0, 0, 0.7071)

```

 

`v`を純粋クォータニオン`p=(0, 1, 0, 0)`として、まず`q×p`を計算する。

 

```

q×p の各成分:

スカラー部: (√2/2)(0) - (0)(1) - (0)(0) - (√2/2)(0) = 0

i成分: (√2/2)(1) + (0)(0) + (0)(0) - (√2/2)(0) = √2/2

j成分: (√2/2)(0) - (0)(0) + (0)(0) + (√2/2)(1) = √2/2

k成分: (√2/2)(0) + (0)(0) - (0)(1) + (√2/2)(0) = 0

 

q×p = (0, √2/2, √2/2, 0)

```

 

次に、この結果に`q⁻¹`(共役クォータニオン`(√2/2, 0, 0, -√2/2)`)を右から掛ける。

 

```

(q×p)×q⁻¹ の各成分(q×p=(0,√2/2,√2/2,0)、q⁻¹=(√2/2,0,0,-√2/2)):

スカラー部: (0)(√2/2) - (√2/2)(0) - (√2/2)(0) - (0)(-√2/2) = 0

i成分: (0)(0) + (√2/2)(√2/2) + (√2/2)(-√2/2) - (0)(0) = 0.5 - 0.5 = 0

j成分: (0)(0) - (√2/2)(-√2/2) + (√2/2)(√2/2) + (0)(0) = 0.5 + 0.5 = 1

k成分: (0)(-√2/2) + (√2/2)(0) - (√2/2)(0) + (0)(√2/2) = 0

 

(q×p)×q⁻¹ = (0, 0, 1, 0)

```

 

得られた結果`(0, 0, 1, 0)`はベクトル部が`(0, 1, 0)`の純粋クォータニオンであり、これはまさに期待した回転結果`(0,1,0)`と完全に一致する。半角(45度)のクォータニオンを使った計算が、正しく全角(90度)の回転を再現することが検算できた。

 

### 2-7. なぜゲーム開発で標準的に使われるのか

 

クォータニオンがオイラー角や回転行列に対して持つ利点は、主に3つある。

 

第一に、**ジンバルロックが起きない**。クォータニオンは4つの成分すべてが対等に絡み合っており、オイラー角のように特定の姿勢で自由度が縮退することがない。

 

第二に、**滑らかな補間ができる**。2つの姿勢の間をなめらかに移り変わらせたいとき、クォータニオンには**球面線形補間(きゅうめんせんけいほかん、Slerp、Spherical Linear Interpolation、水準七: 2つの単位クォータニオンの間を、単位球面上の最短弧に沿って一定の角速度で補間する手法)**という手法が使える。数学者ケン・シューメイク(Ken Shoemake)が1985年の論文でコンピュータグラフィックスに導入したとされるこの手法により、カメラワークやキャラクターの姿勢変化を、不自然な速度のムラなく滑らかに繋ぐことができる。

 

第三に、**データが軽い**。回転行列(3×3で9個の数値、→BOOK-0120で扱われる話題)に対し、クォータニオンはわずか4つの数値で済み、しかも合成(2つの回転を繋げる)は単なるクォータニオンの掛け算1回で完了する。

 

### 深掘りコラム: q と -q は同じ回転を表す(二重被覆)

 

やや発展的な注意点として、あるクォータニオン`q`と、その符号をすべて反転させた`-q`は、サンドイッチ積`qvq⁻¹`の計算結果としてはまったく同じ回転を表す、という性質が知られている(符号の反転が、掛ける側と割る側の両方で2回打ち消し合うため)。この性質は**二重被覆(にじゅうひふく、水準八: 1つの回転に対して、クォータニオンの表現が(符号違いで)ちょうど2つ存在するという数学的構造)**と呼ばれる。実装上は、2つの姿勢を補間する際に`q`と`-q`のどちらを使うかで、最短経路を通るか遠回りするかが変わってしまうことがあるため、多くの実装では2つのクォータニオンの内積の符号を見て、負であれば片方の符号を反転させてから補間する、という対策が取られる。

 

---

 

## 休憩所②: まとめ箱 — 第二章のポイント

 

```

オイラー角の弱点 = ジンバルロック(ピッチ±90度で2軸が重なり、自由度が3→2に縮退)

複素数(2次元回転)の3次元拡張 = クォータニオン(ハミルトン、1843年10月16日、ブルーム橋の逸話)

 

クォータニオン q=(w,x,y,z)、回転はq=(cos(θ/2), sin(θ/2)×axis)という「半角」表現

回転の適用: p'=q×p×q⁻¹(サンドイッチ積。2回作用するため角度が半分で済む)

 

検算: v=(1,0,0)をz軸まわり90度回転→q=(√2/2,0,0,√2/2)でサンドイッチ積を計算→(0,1,0)と完全一致

 

利点: ジンバルロックなし/滑らかな補間(Slerp、Shoemake 1985)/行列より軽量・合成が1回の掛け算

発展: q と -q は同じ回転(二重被覆)

```

 

---

 

## 第三章: 逆行列と法線変換 — 歪めても壊れない向きを求める

 

### 3-1. なぜ「モデル行列をそのまま法線に使う」と壊れるのか

 

3Dモデルを配置するとき、**モデル行列(BOOK-0187第五章で導入)**は、モデル座標系の頂点をワールド座標系の正しい位置・向き・大きさへ変換する行列だった。ここで素朴な疑問が生じる。頂点の**位置**をモデル行列で変換するなら、面の**法線**(第一章で外積を使って求めたベクトル)も、同じモデル行列でそのまま変換すればよいのではないか。

 

結論から言えば、これは**一般には間違っている**。とくにモデルを縦横で異なる倍率に引き伸ばす**非一様スケーリング(ひいちようすけーりんぐ、水準六: x・y・z軸ごとに異なる倍率で拡大縮小する変換。すべての軸を同じ倍率で拡大縮小する一様スケーリングとは区別される)**を行うと、位置と同じ行列を法線にそのまま使った場合、変換後の法線が面に対して垂直でなくなってしまう。この節の後半で、具体的な数値によってこの「壊れ方」を検算する。

 

### 3-2. 逆行列とは何か — BOOK-0071の行列式を使って導出する

 

この問題を解く鍵になるのが**逆行列(ぎゃくぎょうれつ、水準六: ある正方行列Aに対して、掛け合わせると単位行列Iになるような行列。A×A⁻¹=A⁻¹×A=Iを満たすA⁻¹のこと)**である。

 

→BOOK-0120(第三章、固有値と固有ベクトルの節)では、対角化`A=PDP⁻¹`という式の中で、この`P⁻¹`という記号が「Pの逆行列(掛けると単位行列になる相手の行列)」として一度だけ登場していた。しかし、その逆行列を実際にどう計算するかという手順そのものは、BOOK-0120にもBOOK-0071にも書かれていない。ここでは、その計算手順を、BOOK-0071 第四章がすでに導入していた**行列式**`ad-bc`を使って、実際に導出する。

 

2行2列の行列`A = [a b; c d]`の逆行列は、次の式で求められる。

 

```

A⁻¹ = (1/det(A)) × [ d -b ; -c a ] (det(A) = ad - bc)

```

 

つまり、対角成分`a`と`d`を入れ替え、非対角成分`b`と`c`の符号を反転させた行列を、行列式`ad-bc`で割ればよい。行列式が0のときは、この式は0での割り算になってしまうため、逆行列は存在しない(→BOOK-0071第四章が「行列式が0のとき、連立方程式はただ1組の解を持たない」と述べていたことと、同じ事情である。行列式0の行列は、空間をより低い次元へ潰してしまうため、潰す前の状態へ戻す「逆」の操作が原理的に存在しない)。

 

### 3-3. 検算: BOOK-0071の例をそのまま使って2×2逆行列を求める

 

→BOOK-0071 第四章の検算3は、行列`A=[1 2; 3 4]`の行列式が`ad-bc=1×4-2×3=-2`であることを検算していた。この同じ行列を使って、逆行列を求めてみよう。

 

```

A⁻¹ = (1/-2) × [ 4 -2 ; -3 1 ] = [ -2 1 ; 1.5 -0.5 ]

```

 

これが本当に逆行列になっているかを、`A × A⁻¹ = I`(単位行列)を計算して確かめる。

 

```

A × A⁻¹ =

行1: [1×(-2)+2×1.5, 1×1+2×(-0.5)] = [-2+3, 1-1] = [1, 0]

行2: [3×(-2)+4×1.5, 3×1+4×(-0.5)] = [-6+6, 3-2] = [0, 1]

 

結果 = [1 0; 0 1] = I (単位行列と完全に一致)

```

 

BOOK-0071がすでに検算していた行列式`-2`を使って導いた逆行列が、確かに単位行列を生むことが検算できた。

 

なお、3DCGで実際に扱う行列は4×4(あるいは回転・スケールの部分だけを取り出した3×3)であり、2×2よりはるかに複雑になる。一般のn×n行列の逆行列は、各成分を打ち消す**余因子行列(よいんしぎょうれつ、随伴行列、水準七: 行列の各成分を、その成分を除いた小行列の行列式〈符号つき〉に置き換えて作った行列)**を使い、`A⁻¹ = adj(A)/det(A)`という式で一般化できる。ここまで見た2×2の`[d -b; -c a]`という並べ替えは、実はこの余因子行列を2×2という最小のケースに当てはめたものにほかならない。実際の3DCGライブラリの多くは、この一般式をそのままコード化するか、あるいは→BOOK-0071 第二章・第五章で見た**消去法(ガウスの消去法)**を、単位行列という「特別な右辺」に繰り返し適用する**ガウス・ジョルダン法(がうす・じょるだんほう、水準七: 行列Aと単位行列Iを並べた[A|I]という拡大行列に消去法を繰り返し適用し、左側がIになったとき右側に現れるのがA⁻¹である、という手順)**によって、逆行列を数値的に計算している。

 

### 3-4. なぜ転置が必要なのか — 直交条件を保つ

 

逆行列が手に入ったので、いよいよ本題である「法線をどう変換すべきか」に戻ろう。面の法線`N`と、その面上にある任意の接線ベクトル`T`(面に沿った向き)は、定義により常に垂直——→第一章で確認した内積の言葉で言えば`N・T=0`——という関係を保っていなければならない。

 

いま、モデル行列(の回転・スケール部分)を`M`とし、頂点や接線は`T' = M×T`という素直な変換で変換されるとする。変換後も直交条件`N'・T'=0`を保つような、正しい法線の変換行列`G`(`N'=G×N`)を求めたい。

 

```

N'・T' = 0 を満たしたい

(G×N)・(M×T) = 0 が、Nと元々垂直な"すべての"Tについて成り立ってほしい

```

 

この条件は、`G`が`M`の逆行列の転置(`Gᵀ×M = I`、すなわち`G = (M⁻¹)ᵀ`)であるときに成り立つことが、線形代数の一般論として知られている。すなわち、法線ベクトルには、位置ベクトルと同じ行列`M`ではなく、**逆転置行列(ぎゃくてんちぎょうれつ、inverse transpose、水準七: ある行列の逆行列を求めたあと、さらに転置〈行と列を入れ替えること〉した行列。法線ベクトルの正しい変換に使われる)**`(M⁻¹)ᵀ`を使わなければならない。

 

### 3-5. 検算: 回転+非一様スケーリングでの法線変換

 

この理屈を、具体的な数値で検算しよう。2次元で考える(3次元でも考え方はまったく同じである)。モデル行列`M`が、90度回転`R`と、非一様スケーリング(x方向2倍、y方向1倍)`S`を組み合わせたものだとする。

 

```

R = [0 -1; 1 0] (90度回転)

S = [2 0; 0 1] (非一様スケーリング)

 

M = R×S = [0×2+(-1)×0, 0×0+(-1)×1 ; 1×2+0×0, 1×0+0×1] = [0 -1; 2 0]

```

 

面上の接線を`T=(1,1)`、それに垂直な法線を`N=(1,-1)`とする(内積`1×1+1×(-1)=0`で垂直を確認済み)。

 

まず、変換後の接線`T'`を求める。

 

```

T' = M×T = [0×1+(-1)×1, 2×1+0×1] = (-1, 2)

```

 

**ここで、もし法線にも同じ行列Mを使ってしまうと(誤った方法)**、

 

```

N'(誤) = M×N = [0×1+(-1)×(-1), 2×1+0×(-1)] = (1, 2)

```

 

`T'・N'(誤) = (-1)×1 + 2×2 = -1+4 = 3 ≠ 0`

 

垂直でなくなってしまった。これが「モデル行列をそのまま法線に使うと歪む」という現象の、具体的な数値による実演である。

 

**正しい方法(逆転置行列を使う)**で計算し直そう。まず`M`の逆行列を、3-2節の式で求める。

 

```

det(M) = 0×0 - (-1)×2 = 2

M⁻¹ = (1/2) × [0 1 ; -2 0] = [0 0.5 ; -1 0]

```

 

これを転置する(行と列を入れ替える)。

 

```

(M⁻¹)ᵀ = [0 -1 ; 0.5 0]

```

 

この逆転置行列を法線`N=(1,-1)`に掛ける。

 

```

N'(正) = (M⁻¹)ᵀ×N = [0×1+(-1)×(-1), 0.5×1+0×(-1)] = (1, 0.5)

```

 

```

T'・N'(正) = (-1)×1 + 2×0.5 = -1+1 = 0 (垂直、正しく保たれている!)

```

 

同じモデル行列`M`を使ったにもかかわらず、法線には`(M⁻¹)ᵀ`という一段階余分な計算を経由させることで、変換後も直交関係が正しく保たれることが、数値によって検算できた。

 

なお、実装上の注意点として、モデル行列に含まれる**平行移動**の成分は、方向だけを持つ法線ベクトルには無関係(法線は「向き」であって「位置」ではないため、平行移動を適用してはならない)である。実際のコードでは、4×4のモデル行列から回転・スケールの3×3部分だけを取り出し、その3×3部分に対して逆転置を行うのが一般的である。

 

---

 

## 休憩所③: まとめ箱 — 第三章のポイント

 

```

逆行列 A⁻¹: A×A⁻¹=I。2×2では A⁻¹=(1/det(A))×[d -b; -c a](det=ad-bc、BOOK-0071の行列式)

検算1: A=[1,2;3,4](BOOK-0071と同じ例、det=-2)→A⁻¹=[-2,1;1.5,-0.5]→A×A⁻¹=Iを確認

 

なぜ法線はMをそのまま使えないか: 非一様スケーリング等でN・T=0(直交)が壊れるため

正しい変換 = 逆転置行列(M⁻¹)ᵀ

 

検算2: M=回転×非一様スケール=[0,-1;2,0]

誤: N'=M×N→T'・N'=3≠0(垂直が壊れる)

正: N'=(M⁻¹)ᵀ×N→T'・N'=0(垂直を維持、検算成功)

 

一般化: n×n行列は余因子行列/ガウス・ジョルダン法(BOOK-0071の消去法の拡張)で逆行列を求める

```

 

---

 

## 第四章: レイキャスト・ピッキング — BOOK-0187を逆再生する

 

### 4-1. 問いを思い出す: 画面のクリックは、3D空間のどこを指しているのか

 

前書きで立てた本書の主題に、ようやく取り組む準備が整った。→BOOK-0187 第五章が示した**ビューイングパイプライン**は、モデル座標系から始まり、モデル行列・ビュー行列・射影行列という3つの行列を経て、最終的にスクリーン座標系(ピクセル位置)へ至る、一方向の道だった。

 

```

①モデル座標系 →[モデル行列]→ ②ワールド座標系 →[ビュー行列]→ ③カメラ座標系

→[射影行列]→ ④クリップ座標系 →[wで割る]→ ⑤NDC →[ビューポート変換]→ ⑥スクリーン座標系

```

 

**レイキャスト(raycast、水準七: ある始点から特定の方向へ伸びる直線〈レイ、光線〉を仮想的に飛ばし、その直線が3D空間内のどの物体と交差するかを計算によって求める手法)**による**ピッキング(picking、水準六: マウスのクリックなど、画面上の1点の指定から、その点が3D空間のどの物体を指しているかを特定する操作)**は、この道を⑥から①へ向かって逆再生する計算である。第三章で手に入れた逆行列(と逆転置行列ではなく、こちらは素直な逆行列)が、ここで本領を発揮する。

 

### 4-2. ステップ1: スクリーン→NDCの逆変換

 

このステップは、実は→BOOK-0187 第四章の「検算の逆算チェック」で、すでに一度導出されていた。BOOK-0187は、順方向の変換式`screen_x=(ndc_x+1)/2×W`から、逆方向の式を導いていた。

 

```

ndc_x = (screen_x / W) × 2 - 1

ndc_y = 1 - (screen_y / H) × 2

```

 

BOOK-0187の検算例で使われたスクリーン座標`(307.2, 153.6)`(画面512×512)に、この式をそのまま当てはめると、

 

```

ndc_x = (307.2/512)×2-1 = 0.6×2-1 = 0.2

ndc_y = 1-(153.6/512)×2 = 1-0.3×2 = 0.4

```

 

BOOK-0187がすでに検算していた通り、NDC座標`(0.2, 0.4)`が得られる。ここまではBOOK-0187の復習である。本書がここから新しく踏み込むのは、次のステップ——NDCから、さらにクリップ座標・カメラ座標へと戻る計算である。

 

### 4-3. ステップ2〜3: NDC→クリップ→カメラ座標系(射影行列の逆行列)

 

ピッキングの厄介な点は、クリックされた1点`(px, py)`だけでは**奥行き(深度)が分からない**ことである。そこで、NDCの奥行き成分(z)に、**近平面(z_ndc=0)と遠平面(z_ndc=1)**という2つの仮の値を代入し、「近平面上のこの点」と「遠平面上のこの点」という2つの3D点を求め、その2点を結ぶ直線をレイとする、という手法をとる(→BOOK-0187 第四章の検算例では、この射影行列がNDCのz成分を0〜1の範囲に収める設計であったことを確認済みである)。

 

NDC座標`(ndc_x, ndc_y, ndc_z)`に対応するクリップ座標は、任意のw(ここではw=1を選ぶ。→BOOK-0187第三章の「同次座標はwに関してスケール不変」という性質により、w=1を選んでも他の値を選んでも同じNDCを表すため、計算の都合でw=1としてよい)を使って、`(ndc_x×w, ndc_y×w, ndc_z×w, w)`と書ける。

 

```

clipNear = (0.2, 0.4, 0, 1) (近平面、ndc_z=0)

clipFar = (0.2, 0.4, 1, 1) (遠平面、ndc_z=1)

```

 

これらに、BOOK-0187 第四章の射影行列(FOV=90度・aspect=1・near=1・far=100)の**逆行列**を掛ける。この射影行列は

 

```

Pmat = [ 1 0 0 0 ; 0 1 0 0 ; 0 0 100/99 -100/99 ; 0 0 1 0 ]

```

 

という形をしていた。この行列は、1・2行目/列目が単位行列、3・4行目/列目が独立した2×2の部分行列という**ブロック対角**の構造を持つため、逆行列もブロックごとに求めればよい。3・4成分が作る2×2の部分`B=[100/99 -100/99; 1 0]`について、3-2節の式(`det(B)=100/99`)を適用すると、

 

```

B⁻¹ = [0 1 ; -99/100 1]

```

 

となり(`B×B⁻¹=I`であることは、実際に掛け合わせて確認できる)、Pmat全体の逆行列は次のようになる。

 

```

Pmat⁻¹ = [ 1 0 0 0 ; 0 1 0 0 ; 0 0 0 1 ; 0 0 -99/100 1 ]

```

 

### 4-4. 検算: BOOK-0187の例を逆にたどる

 

このPmat⁻¹を、クリップ座標の近平面・遠平面それぞれに適用してみよう。

 

```

Pmat⁻¹ × clipNear = Pmat⁻¹ × (0.2, 0.4, 0, 1)

= (1×0.2, 1×0.4, 0×0+1×1, (-99/100)×0+1×1) = (0.2, 0.4, 1, 1)

```

 

w成分(1)で割ると(w=1なのでそのまま)、カメラ座標系での近平面上の点は`(0.2, 0.4, 1)`。**z成分がちょうど1、すなわちnear=1と完全に一致する**——これは近平面の定義そのものであり、計算が正しいことの第一の確認になる。

 

```

Pmat⁻¹ × clipFar = Pmat⁻¹ × (0.2, 0.4, 1, 1)

= (0.2, 0.4, 0+1×1, (-99/100)×1+1×1) = (0.2, 0.4, 1, 0.01)

```

 

w成分(0.01)で割ると、`(0.2/0.01, 0.4/0.01, 1/0.01) = (20, 40, 100)`。**z成分がちょうど100、すなわちfar=100と完全に一致する**——遠平面の定義とも一致し、二重の確認がとれた。

 

したがって、カメラ座標系での近平面上の点は`cameraNear=(0.2, 0.4, 1)`、遠平面上の点は`cameraFar=(20, 40, 100)`である。この2点を結ぶ直線が、クリックされたピクセルから飛ばすべきレイである。

 

**最終検算(往復確認)**: このレイが、BOOK-0187が使っていた元の点`(1, 2, 5)`を本当に通るかどうかを確認しよう。レイ上の点は`P(t) = cameraNear + t×(cameraFar - cameraNear) = (0.2, 0.4, 1) + t×(19.8, 39.6, 99)`と書ける。z成分が5になる`t`を求めると、

 

```

1 + 99t = 5 → t = 4/99 ≈ 0.0404

```

 

このtをx成分・y成分にも代入すると、

 

```

x = 0.2 + 19.8×(4/99) = 0.2 + 79.2/99 = 0.2 + 0.8 = 1.0

y = 0.4 + 39.6×(4/99) = 0.4 + 158.4/99 = 0.4 + 1.6 = 2.0

```

 

x=1.0、y=2.0——**BOOK-0187の元の点`(1, 2, 5)`と、小数点以下まで完全に一致する**。深度情報を一切使わず、スクリーン上の1点`(307.2, 153.6)`だけから出発した逆算が、BOOK-0187が順方向の計算で使っていた3D空間上の点を、正確に再発見できることが検算された。

 

なお、このレイはまだ**カメラ座標系**にある。実際のゲームエンジンでは、ここからさらに**ビュー行列の逆行列**(View⁻¹)を掛けることで、ワールド座標系へ変換する。カメラ座標系は、ワールド座標系をカメラの位置・向きを基準に測り直したものだった(→BOOK-0187第五章)ため、その逆変換にも、本章・前章で扱ったのと同じ「逆行列」という考え方がそのまま使える。

 

### 4-5. レイと図形の交差判定 — レイ-平面

 

レイが定まったら、次はそのレイが実際にどの物体と交差するかを判定する。レイを`P(t) = O + tD`(`O`=始点、`D`=正規化された方向ベクトル、`t≥0`)と表す。

 

平面が、平面上のある点`Q`と法線`N`(単位ベクトル、→第一章・第三章参照)によって定義されているとする。平面上の任意の点`P`は`N・(P-Q)=0`を満たす。ここに`P(t)=O+tD`を代入すると、

 

```

N・(O+tD-Q) = 0

N・(O-Q) + t(N・D) = 0

t = N・(Q-O) / (N・D)

```

 

`N・D=0`のときはレイが平面に平行(交差しない、または平面上に乗っている)。`t<0`のときは交点がレイの始点より後ろにあり、実際には見えない。

 

**検算**: 地面を表す平面(z=0、法線`N=(0,0,1)`、平面上の点`Q=(0,0,0)`)に、上空からレイ`O=(0,5,10)`、`D=(0,-1,-2)`(正規化前)を飛ばす。

 

```

N・D = 0×0+0×(-1)+1×(-2) = -2

N・(Q-O) = (0,0,1)・(0-0, 0-5, 0-10) = (0,0,1)・(0,-5,-10) = -10

t = -10 / -2 = 5

```

 

```

P(5) = O + 5D = (0,5,10) + 5×(0,-1,-2) = (0, 5-5, 10-10) = (0, 0, 0)

```

 

ちょうど平面上の点`(0,0,0)`と一致し、交差が正しく検算できた。

 

### 4-6. レイと図形の交差判定 — レイ-球

 

中心`C`、半径`r`の球との交差を考える。`L=O-C`(始点から球の中心への逆ベクトル)とおくと、`|P(t)-C|²=r²`という条件は、tについての2次方程式に整理できる。

 

```

(D・D)t² + 2(L・D)t + (L・L - r²) = 0

```

 

Dが正規化されている(`D・D=1`)場合、この2次方程式の**判別式**(→BOOK-0071が代数の話題として触れた判別式と同じ考え方)は

 

```

Δ = (L・D)² - (L・L - r²)

```

 

であり、`Δ<0`なら交差なし、`Δ=0`なら接する(1点)、`Δ>0`なら2点で交差する(手前の交点と奥の交点)。交点のtは

 

```

t = -(L・D) ± √Δ

```

 

**検算**: 球の中心`C=(0,0,5)`、半径`r=2`。レイの始点`O=(0,0,0)`、方向`D=(0,0,1)`(正規化済み、+z方向にまっすぐ)。

 

```

L = O-C = (0,0,-5)

L・D = 0×0+0×0+(-5)×1 = -5

L・L = 0+0+25 = 25

Δ = (-5)² - (25-4) = 25-21 = 4

√Δ = 2

t = -(-5) ± 2 = 5±2 → t=3 または t=7

```

 

```

P(3) = O+3D = (0,0,3)。|P(3)-C| = |(0,0,3)-(0,0,5)| = |(0,0,-2)| = 2 = r (球面上、確認できた)

P(7) = O+7D = (0,0,7)。|P(7)-C| = |(0,0,7)-(0,0,5)| = |(0,0,2)| = 2 = r (球面上、確認できた)

```

 

手前の交点(t=3、球の表側)と奥の交点(t=7、球の裏側)の両方が、半径2の球面上にちょうど乗っていることが検算できた。ピッキングの実装では、複数の物体候補と交差判定を行い、最も小さい(手前の)tを持つ交点を「クリックで選ばれた物体」として採用する。

 

### 深掘りコラム: たくさんの物体があるときの高速化

 

本章で見た交差判定は、シーン内の物体1つ1つに対して律儀に計算すれば必ず正しい答えが出るが、物体の数が数千・数万に増えると、すべての物体に対して毎回この計算を行うのは非効率になる。この問題への対策として、物体をあらかじめ箱状の領域(バウンディングボックス)でまとめて木構造に整理しておく**BVH(バウンディングボリューム階層、水準八)**のような空間分割の技法が広く使われているが、この高速化技法自体は本書の範囲を超えるため、ここでは名前の紹介にとどめる。

 

---

 

## 休憩所④: まとめ箱 — 第四章のポイント

 

```

ピッキング = BOOK-0187のビューイングパイプラインを逆再生する計算

 

手順:

①スクリーン→NDC(BOOK-0187の逆算チェックを再利用): ndc=(0.2,0.4)

②NDCのz(0=近平面/1=遠平面)を仮定し、射影行列の逆行列Pmat⁻¹でカメラ座標系へ

③カメラ座標→ワールド座標(ビュー行列の逆行列、概念のみ)

 

検算: BOOK-0187の例(FOV90°,near1,far100)を逆算

cameraNear=(0.2,0.4,1)[near=1と一致]、cameraFar=(20,40,100)[far=100と一致]

→レイ上のt=4/99で元の点(1,2,5)を完全再現(深度情報なしで復元成功)

 

レイ-平面: t=N・(Q-O)/(N・D) → 検算t=5で平面上と一致

レイ-球: (D・D)t²+2(L・D)t+(L・L-r²)=0、判別式Δ → 検算t=3,7で球面上と一致(2交点)

```

 

---

 

## 第五章: ジオメトリ生成の基礎 — 頂点からシェーダへ

 

### 5-1. 頂点・法線・UV座標という3点セット

 

3DCGにおける1つの「形」は、多くの場合、**頂点(ちょうてん、水準五: 3Dモデルを構成する、位置を持つ最小単位の点)**の集まりとして表現される。実装上、各頂点は単なる位置`(x,y,z)`だけでなく、次の3つの情報をセットで持つことが多い。

 

- **位置**: モデル座標系での`(x,y,z)`

- **法線**: その頂点(または面)がどちらを向いているか(→第一章・第三章)

- **UV座標(ゆーぶいざひょう、テクスチャ座標、水準五: 3Dモデルの表面に、平面の画像〈テクスチャ〉をどう貼り付けるかを指定する、0から1の範囲の2次元座標)**

 

### 5-2. 立方体の生成 — なぜ8頂点ではなく24頂点なのか

 

立方体は8つの角(頂点)しか持たないはずなのに、実際の3DCG実装では、しばしば**24個**の頂点データを用意する。理由は、各面の法線を正しく扱うためである。

 

立方体の1つの角(たとえば`(1,1,1)`)は、実は3つの面(前面・上面・右面)に同時に属している。もしこの角を1つの頂点データとして共有してしまうと、その頂点はどの面の法線を持てばよいのか決まらなくなる(3つの面の法線を平均するとエッジがぼやけた印象になり、立方体らしいくっきりした稜線が失われる)。

 

そこで実務上は、6つの面それぞれに専用の4頂点(6面×4頂点=24頂点)を用意し、同じ空間位置`(1,1,1)`であっても、所属する面が違えば別々の頂点データ(位置は同じでも法線とUVが異なる)として扱う。こうすることで、面ごとにくっきりと異なる法線を持たせることができる。

 

### 5-3. 巻き順と外積の関係 — 検算

 

各面は、4頂点をそのまま描画するのではなく、2つの三角形に分割して描画するのが一般的である。このとき、三角形の頂点をどの順序で並べるかという**巻き順(まきじゅん、winding order、水準六: 三角形の頂点を反時計回りに並べるか、時計回りに並べるかという規則)**が、外積(→第一章)によって計算される面法線の向きを直接左右する。

 

多くのライブラリでは、**外側から見て反時計回り**に頂点を並べた三角形の法線が、外向き(視点側)を向くという規則を採用している(この規則を使い、裏側を向いた三角形の描画を省略する最適化を**バックフェイスカリング**〈back-face culling、水準六: カメラから見て裏を向いている面の描画を省略し、計算量を削減する手法〉と呼ぶ)。

 

**検算**: 立方体の上面(y=1の面)を、外側(+y方向、真上)から見て反時計回りに次のように並べる。

 

```

v0=(-1,1,-1), v1=(-1,1,1), v2=(1,1,1), v3=(1,1,-1)

```

 

```

edge1 = v1-v0 = (0,0,2)

edge2 = v3-v0 = (2,0,0)

 

edge1×edge2 = (0×0-2×0, 2×2-0×0, 0×0-0×2) = (0, 4, 0)

```

 

正規化すると`(0,1,0)`——真上を向く法線であり、上面の法線として正しいことが検算できた。第一章で確認した前面の例(z=1の面、反時計回りに並べて外積を取ると(0,0,1))と合わせて、「外側から見て反時計回りに頂点を並べれば、外積の右手系の性質により、法線は自動的に外向きになる」という規則が、2つの異なる面で一貫して成り立つことが確認できた。

 

### 5-4. 球の生成 — UV球のパラメトリック方程式

 

球の頂点生成には、緯度・経度のように格子状に分割する**UV球(ゆーぶいきゅう、緯度経度球、水準六: 極から極までを「緯度」方向に、赤道を一周する「経度」方向に、それぞれ格子状に分割して頂点を生成する球のモデリング手法)**が広く使われる。半径`r`、縦の分割数`stacks`、横の分割数`slices`とし、縦方向のインデックスを`i`(0〜stacks)、横方向のインデックスを`j`(0〜slices)とすると、各頂点の位置は次の式で求まる。

 

```

θ(シータ、極からの角度) = (i / stacks) × π (0〜π)

φ(ファイ、赤道方向の角度) = (j / slices) × 2π (0〜2π)

 

x = r × sin(θ) × cos(φ)

y = r × cos(θ)

z = r × sin(θ) × sin(φ)

```

 

球の法線には、立方体にはない美しい性質がある。球の中心が原点にある限り、**法線は中心から頂点への方向、つまり位置ベクトルを正規化するだけで求まる**(`normal = (x,y,z)/r`)。これは、球面上のどの点でも、その点を通る半径の延長線がちょうどその点での接平面に垂直になる、という球の幾何学的な性質による。

 

UV座標は`u = j/slices`、`v = i/stacks`とするのが一般的である。

 

### 5-5. 検算: 球面上の1頂点

 

半径`r=3`、`stacks=4`、`slices=4`の球で、`i=1`、`j=1`の頂点を計算してみよう。

 

```

θ = (1/4)×π = π/4 = 45°

φ = (1/4)×2π = π/2 = 90°

 

sin(45°) = cos(45°) = √2/2 ≈ 0.7071

cos(90°) = 0、sin(90°) = 1

 

x = 3×0.7071×0 = 0

y = 3×0.7071 = 2.1213

z = 3×0.7071×1 = 2.1213

```

 

この頂点`(0, 2.1213, 2.1213)`が、本当に半径3の球面上にあるかを検算する。

 

```

|頂点| = √(0² + 2.1213² + 2.1213²) = √(4.5 + 4.5) = √9 = 3 = r (球面上、確認できた)

```

 

(`2.1213² = (3×√2/2)² = 9×2/4 = 4.5`は近似ではなく正確な値であるため、この検算は丸め誤差なく厳密に一致する。)

 

法線は`(0, 2.1213, 2.1213)/3 = (0, 0.7071, 0.7071)`となり、その長さも`√(0+0.5+0.5)=1`と、正しく単位ベクトルになっていることが確認できる。

 

### 深掘りコラム: アイコスフィアという選択肢

 

UV球には、極(θ=0とθ=πの付近)で経度方向の頂点が1点に collapse し、頂点の密度が極端に偏るという弱点がある(地球儀の緯線が、極に近づくほど短くなることを思い出すとよい)。この偏りを避ける代替案が**アイコスフィア(icosphere、水準七: 正二十面体〈20枚の正三角形でできた立体〉の各面をさらに小さな三角形に再帰的に分割し、それぞれの頂点を球面上に押し出して作る球のモデリング手法)**である。頂点密度が球面上でほぼ均一になる利点があるが、UV座標の割り当てが直感的でなくなる、分割の再帰計算がやや複雑になる、という代償もある。用途(見た目の均一性を優先するか、UVマッピングのしやすさを優先するか)に応じて選択されることが多い。

 

### 5-6. GLSL/WebGLシェーダの基本構造

 

こうして生成した頂点データ(位置・法線・UV)は、最終的に**GLSL(ジーエルエスエル、OpenGL Shading Language、水準六: GPU上で動く、頂点やピクセルごとの計算を記述するための専用プログラミング言語)**で書かれた**シェーダ(shader、水準六: GPU上で並列に実行される、描画処理専用の小さなプログラム)**によって画面に描かれる。3DCGの標準的なシェーダパイプラインは、大きく2つの段階に分かれる。

 

**頂点シェーダ(ちょうてんしぇーだ、vertex shader、水準六: 頂点1つ1つに対して1回ずつ実行され、頂点の位置をクリップ座標系へ変換する役割を持つシェーダの段階)**は、頂点の位置・法線などを受け取り、モデル・ビュー・射影行列(→BOOK-0187第五章)を掛けてクリップ座標を出力する。

 

```glsl

// 頂点シェーダの例(簡略化)

attribute vec3 aPosition;

attribute vec3 aNormal;

uniform mat4 uModelViewProjection; // 射影×ビュー×モデル(BOOK-0187第五章)

uniform mat3 uNormalMatrix; // (モデル行列の3x3部分)の逆転置行列(本書第三章)

varying vec3 vNormal; // フラグメントシェーダへ橋渡しする値

 

void main() {

gl_Position = uModelViewProjection * vec4(aPosition, 1.0);

vNormal = uNormalMatrix * aNormal; // 第三章の逆転置行列がここで実際に使われる

}

```

 

**フラグメントシェーダ(ふらぐめんとしぇーだ、fragment shader、ピクセルシェーダとも、水準六: ラスタライズ〈BOOK-0187第六章〉によって生成された、描画候補の点(フラグメント)1つ1つに対して1回ずつ実行され、最終的な色を決めるシェーダの段階)**は、頂点シェーダから補間されて渡された値(varying)を受け取り、最終的な色を計算する。

 

```glsl

// フラグメントシェーダの例(簡略化・簡単なライティング)

precision mediump float;

varying vec3 vNormal;

uniform vec3 uLightDir; // 光源の方向

 

void main() {

// 内積(BOOK-0071)で「法線と光源方向がどれだけ揃っているか」を測る

float brightness = max(dot(normalize(vNormal), normalize(uLightDir)), 0.0);

gl_FragColor = vec4(vec3(brightness), 1.0);

}

```

 

頂点シェーダは頂点の数だけ、フラグメントシェーダは画面のピクセル(に対応する候補点)の数だけ、GPU上でそれぞれ大量に並列実行される。この「位置の計算(頂点シェーダ)」と「色の計算(フラグメントシェーダ)」を分業させる設計が、現代のリアルタイム3DCGの基本構造である。

 

### 5-7. すべてをつなぐ

 

このわずか2つの短いシェーダコードの中に、本書で扱ってきた道具のほとんどが実際に姿を現している。`uNormalMatrix`は第三章の逆転置行列であり、その素材となる面法線は第一章の外積によって求められ、`dot(normalize(vNormal), normalize(uLightDir))`という1行は、→BOOK-0071の内積の定義そのものが、ライティング計算という具体的な仕事をしている瞬間である。そして`uModelViewProjection`は→BOOK-0187が導出した行列の連鎖であり、これを画面のピクセルへ変換するラスタライズも、同じくBOOK-0187第六章の仕事である。3DCGの実装は、これらの道具が組み合わさって初めて動く、一つの大きな仕掛けなのである。

 

---

 

## 休憩所⑤: まとめ箱 — 第五章のポイント

 

```

頂点の3点セット = 位置・法線・UV座標

 

立方体 = 24頂点(6面×4頂点)。角を面ごとに独立させ、面ごとにくっきりした法線を持たせる

巻き順(外側から反時計回り)→外積(第一章)で法線が自動的に外向きになる

検算: 立方体上面のedge1=(0,0,2)、edge2=(2,0,0)→外積(0,4,0)→正規化で法線(0,1,0)

 

UV球: θ=(i/stacks)π、φ=(j/slices)2π、位置=r(sinθcosφ, cosθ, sinθsinφ)

球の法線 = 位置ベクトルを正規化するだけ(球ならではの性質)

検算: r=3,i=1,j=1→頂点(0,2.1213,2.1213)→|頂点|=√9=3=rと厳密に一致

 

GLSL: 頂点シェーダ(位置→クリップ座標、法線に逆転置行列を適用)

フラグメントシェーダ(内積でライティング計算、色を出力)

```

 

---

 

## 実装のこつ集 — 現場で迷ったときの判断材料

 

→BOOK-0187の「達人術集」に倣い、本書の内容を実務に落とし込む際に迷いやすい点を4つ、判断材料として収録する(正式な技-ID採番は司令塔側の台帳管理に委ねるため、本書ではあえて技-番号を付さない)。

 

**その1: 外積の符号ミスを疑ったら、内積による逆算チェックをする**

 

適用条件: 外積の計算結果が、期待した向きと逆になっている(あるいは0ベクトルになる)気がするとき。

目安範囲: 求めた外積`a×b`と、元の2つのベクトル`a`・`b`それぞれとの内積をとり、両方とも0になるかを確認する(→第一章1-5節)。0にならない場合、成分の掛け算・引き算の順序を取り違えている可能性が高い。0ベクトルになる場合は、`a`と`b`が平行(またはどちらかが0ベクトル)であり、外積が定義上意味を持たない状況である。

 

**その2: クォータニオンの補間前には、内積の符号を確認する**

 

適用条件: 2つの姿勢(クォータニオン)の間をSlerpで補間したとき、意図しない大回りの回転になる。

目安範囲: →第二章の深掘りコラムで触れた通り、`q`と`-q`は同じ回転を表す(二重被覆)。補間対象の2つのクォータニオンの内積が負であれば、どちらか一方の符号をすべて反転してから補間することで、最短経路の回転を選び直せる。

 

**その3: ピッキングのレイでは、near/farの選び方と`t<0`の除外を忘れない**

 

適用条件: →第四章のレイキャストを実装したのに、意図しない物体が選ばれる、あるいは何も選ばれない。

目安範囲: レイと物体の交差判定で得られた`t`が負の場合、その交点はレイの始点より後ろ(カメラの後方)にあり、実際には見えていない。複数の交点候補がある場合は、`t≥0`を満たす中で最小の`t`(最も手前の交点)を採用する。またnear平面をカメラに近づけすぎると(→BOOK-0187達人術・技-ZOU-008のZファイティングと同種の理由で)、near/far間のNDC z値の分布が偏り、ピッキングの精度が落ちる場合がある。

 

**その4: 法線行列(逆転置行列)が省略できる特別な場合を知っておく**

 

適用条件: モデル行列に非一様スケーリングが含まれていない(回転・平行移動・一様スケーリングのみ)と分かっているとき。

目安範囲: モデル行列`M`が「回転`R`×一様スケール`s`」(`M=sR`)という形のとき、`M`の逆転置行列は`(M⁻¹)ᵀ=(1/s²)×R=(1/s)×M`となり、`M`自身の定数倍に一致する。フラグメントシェーダで法線を`normalize()`する実装(→第五章5-6節のコード例)であれば、定数倍は正規化によって消えてしまうため、この場合に限り、逆転置行列を省略してモデル行列(の3×3部分)をそのまま法線に使っても、最終的な見た目は変わらない。ただし非一様スケーリングが少しでも混じるモデルには、この近似は使えない。

 

---

 

## 終章 — 額縁の中から届いた手

 

本書は、→BOOK-0187が固定した「カメラ→スクリーン」という片道の射影数学に対し、その逆方向と、3DCG実装で必須になる周辺の道具一式を扱ってきた。第一章では、内積(BOOK-0071)とは異なる「もう一つの掛け算」である外積を手に入れ、面の向きと面積を計算できるようになった。第二章では、オイラー角のジンバルロックという落とし穴を、複素数の拡張であるクォータニオンによって回避する方法を見た。第三章では、BOOK-0071の行列式を使って逆行列を実際に導出し、非一様なスケーリングを受けても法線が壊れない、逆転置行列という補正を検算した。第四章では、いよいよ本書の主題である「クリックの先にある世界」——BOOK-0187のビューイングパイプラインを逆再生し、スクリーン上の1点から、深度情報なしにワールド空間のレイを再構成する手順を、BOOK-0187自身の数値例を使って完全に検算した。そして第五章では、ここまでのすべての道具(外積・逆転置行列・内積)が、実際のGLSLシェーダコードの中でどう再会するかを見届けた。

 

### ギャップ台帳との対応

 

CLAUDE.md「ギャップ駆動辞書拡充規約」に基づき`outputs/dictionary_gaps.json`に記録されていた6件のギャップのうち、本書が扱った5件は、それぞれ次の章で解消された。

 

```

GAP-0006(外積) → 第一章で解消

GAP-0007(クォータニオン) → 第二章で解消

GAP-0009(逆行列・法線変換) → 第三章で解消

GAP-0008(レイキャスト・ピッキング) → 第四章で解消

GAP-0010(ジオメトリ生成・GLSL) → 第五章で解消

```

 

### GAP-0011への誠実な線引き

 

残るGAP-0011は、「FUNC辞書(コード生成カード側)の38ドメインに『3D』『幾何』『物理演算』というドメインが構造単位で欠落している」という、gakumon(理論・書籍側)とは別の辞書体系についての所見だった。本書はgakumon側の理論的な穴——3D幾何学の考え方そのものが、どの書籍にも書かれていなかったという穴——を埋めるものであり、実際に、外積・クォータニオン・逆行列による法線変換・レイキャスト・ジオメトリ生成という5つの具体的な概念について、検算つきの解説を提供した。

 

しかし、FUNC辞書側に存在する「コードとしてすぐ呼び出せるカード」が3D/物理演算ドメインで構造的に不足しているという問題は、本書を読んだだけでは解消されない。理論を知っていることと、その理論をカード化・関数化して即座に呼び出せる形に整備することは、別の作業である。この整備はFUNC辞書というコード生成カード側の管轄であり、本書(gakumon側)の範囲外であることを、ここに誠実に明記しておく。

 

### 3冊(4冊)の関係地図

 

```

BOOK-0071(線形代数・水準一〜四) BOOK-0187(射影数学・水準四〜八)

ベクトル・行列・行列式・固有値の入口 カメラ→スクリーン(片道)

│ │

▼ ▼

BOOK-0120(線形代数・水準五〜六) 本書が逆方向(第四章)を担当

対角化・スペクトル定理・P⁻¹が初登場 │

│ │

└──────────────┬─────────────────────┘

▼

BOOK-0226 本書(水準五〜八)

外積(第一章)・クォータニオン(第二章)・逆行列と法線変換(第三章、

BOOK-0071の行列式を継承)・レイキャスト(第四章、BOOK-0187を逆再生)・

ジオメトリ生成とシェーダ(第五章、すべてが1本のコードで再会する)

```

 

BOOK-0071とBOOK-0120が「数の表をどう計算するか」という一般論を、BOOK-0187が「カメラ座標を一方向にスクリーンへ落とし込む数式」を担当してきたのに対し、本書はこの2系統が実装の現場で交差する地点——3DCGを実際に手で組み立てるときに必要になる、しかしどちらの系統の巻にも収まりきらなかった道具一式——を担当した。額縁の中から手を伸ばした先に、もう一度、確かな世界が広がっていたことを、本書の検算群が裏づけている。

 

---

 

## 章末: 簡易階段図(3DCG幾何学の実装数学を積み上げる階段)

 

```

[水準五] 外積: もう一つの掛け算(BOOK-0071の内積と対をなす)

面法線・面積 → 検算: cross((2,0,0),(0,2,0))=(0,0,4)、正規化で(0,0,1)

▲

│ 2つのベクトルから、両方に垂直な第3のベクトルを作る

[水準六] クォータニオン: 4つの数で3次元回転を表す

ジンバルロックなし・半角の理由(サンドイッチ積は2回作用) → 検算: 90°回転で(1,0,0)→(0,1,0)

▲

│ オイラー角の落とし穴(ジンバルロック)を、複素数の拡張で回避する

[水準六〜七] 逆行列と法線変換: 逆転置行列という補正

BOOK-0071の行列式ad-bcで2×2逆行列を導出 → 検算: A=[1,2;3,4]のA⁻¹でA×A⁻¹=Iを確認

▲

│ モデル行列をそのまま法線に使うと、非一様な変形で直交性が壊れる

[水準七〜八] レイキャスト・ピッキング: BOOK-0187を逆再生する

射影行列の逆行列でスクリーンの1点からレイを再構成 → 検算: (307.2,153.6)→(1,2,5)を完全再現

▲

│ BOOK-0187が固定した「カメラ→スクリーン」の一方通行を、逆再生する

[水準五〜六] ジオメトリ生成: 頂点・法線・UVという3点セット

24頂点の立方体・UV球のパラメトリック生成・GLSLの頂点/フラグメントシェーダ

│

└── すべての章の道具(外積・逆転置行列・内積)が、実際のシェーダコード1本の中で再会する

 

横の広がり:

[水準六] 外積(2ベクトル→1ベクトル、3次元限定) ←(対比)→ 内積(2ベクトル→1スカラー、BOOK-0071)

[水準六] クォータニオン(4次元で3次元回転を表現) ←(対比)→ 回転行列(3×3・9数で表現、BOOK-0120)

[水準七] レイ-平面交差(1次方程式) ←(対比)→ レイ-球交差(2次方程式・判別式Δ)

 

現在のフロンティア(第二章・第四章):

クォータニオンをさらに拡張し回転と平行移動を同時に扱う「デュアルクォータニオン」による

スキニング(骨格変形)の統一的表現、およびリアルタイムレイトレーシングのためのBVH高速化は、

いずれも現役の実装課題であり、2020年代にGPUのハードウェアレイトレーシング機能(RTコア等)が

普及したことで、この分野の実務的な重要性がさらに高まっているとされる。

 

次の冊子への矢印:

本書の続巻を正式に予告することは避ける(→BOOK-0002の予告が実装とズレた教訓・

GAKUMON_UNIVERSE.md終章の階段図規約に倣う)。ただし本書が閉じた地点から自然に続きうる候補として、

骨格アニメーション(スキニング)、球面線形補間(Slerp)の詳細な導出、空間分割による

レイキャスト高速化(BVH)などが考えられる、という所見のみを残す。

```

 

---

 

## 参照文献(公的資料・専門機関・教科書的資料)

 

1. Weisstein, Eric W., "Cross Product," MathWorld — 外積の定義・幾何学的性質に関する数学参考資料。

2. O'Connor, J.J. and Robertson, E.F., "Quaternions," MacTutor History of Mathematics Archive, University of St Andrews — ハミルトンによる四元数の発見(1843年10月16日、ブルーム橋の逸話)に関する数学史資料。

3. Hamilton, W. R., "On Quaternions" — ハミルトン自身による四元数の原典的な記述(王立アイルランド科学アカデミーへの報告)。

4. Shoemake, Ken, "Animating Rotation with Quaternion Curves," ACM SIGGRAPH Computer Graphics, 1985 — 球面線形補間(Slerp)をコンピュータグラフィックスに導入した原論文。

5. Akenine-Möller, T., Haines, E., Hoffman, N., *Real-Time Rendering* — 逆転置行列による法線変換、クォータニオンの実装、レイ交差判定を扱うリアルタイムCG分野の代表的教科書。

6. Dunn, F. and Parberry, I., *3D Math Primer for Graphics and Game Development* — 外積・クォータニオン・レイキャストなど、本書全体の主題を扱うゲーム開発向け数学教科書。

7. Lengyel, Eric, *Mathematics for 3D Game Programming and Computer Graphics* — 逆転置行列による法線変換、ジオメトリ生成の数学的基礎を扱う教科書。

8. Möller, T. and Trumbore, B., "Fast, Minimum Storage Ray-Triangle Intersection," Journal of Graphics Tools, 1997 — レイ-三角形交差判定の代表的な高速アルゴリズムに関する原論文(本書のレイ-平面・レイ-球判定の発展として参照)。

9. Scratchapixel, "A Minimal Ray-Tracer: Rendering Simple Shapes" — レイ-球交差判定の導出に関する公開技術解説資料。

10. Khronos Group, "OpenGL Shading Language (GLSL) Specification" — GLSLの言語仕様に関する公式資料。

11. Khronos Group, "WebGL Specification" — WebGLの仕様に関する公式資料。

12. MDN Web Docs, "WebGL model view projection" / "Using shaders to apply color in WebGL" — 頂点シェーダ・フラグメントシェーダの役割分担に関する開発者向け技術解説。

13. Segal, M. and Akeley, K., *The OpenGL Programming Guide*("Red Book") — 法線行列(逆転置行列)の実装上の扱いに関する伝統的なリファレンス。

14. Bourke, Paul, "Platonic Solids" — アイコスフィア(正二十面体の再帰分割による球生成)に関する技術解説資料。

15. Songho, "OpenGL Sphere" — UV球(緯度経度分割による球のジオメトリ生成)のパラメトリック方程式に関する技術解説資料。

16. Ericson, Christer, *Real-Time Collision Detection* — バウンディングボリューム階層(BVH)によるレイキャスト高速化に関する代表的教科書。

 




# BOOK-0226 情報派生_3DCG幾何学の実装数学 — クリックの先にある世界へ(第1巻)
  1. 目次
  2. 小説情報
  3. 縦書き
  4. しおりを挟む
  5. お気に入り登録
  6. 評価
  7. 感想
  8. ここすき
  9. 誤字
  10. 閲覧設定