# 機能設計書 149-QuaternionLinearInterpolant

## 概要

本ドキュメントは、Three.jsライブラリにおけるQuaternionLinearInterpolant（四元数線形補間）機能の設計について記述する。QuaternionLinearInterpolantは、Interpolant基底クラスを継承し、四元数の球面線形補間（SLERP: Spherical Linear Interpolation）を提供する。

### 本機能の処理概要

QuaternionLinearInterpolantは、2つの四元数（回転を表す）間を滑らかに補間するためのSLERP補間器である。単純な線形補間と異なり、回転の最短経路を通り、一定の角速度で補間を行う。

**業務上の目的・背景**：3Dアニメーションにおいて、オブジェクトの回転を補間する際に単純な成分ごとの線形補間を行うと、回転軸がぶれたり、回転速度が不均一になったりする問題がある。四元数のSLERP補間は、単位球面上の2点間を最短距離で移動する大円に沿って補間を行うため、自然で滑らかな回転遷移を実現できる。これはスケルタルアニメーション、カメラ回転、オブジェクトの向きのアニメーションなど、あらゆる回転を伴うアニメーションで必須の技術である。

**機能の利用シーン**：
- スケルタルアニメーションでのボーン回転
- カメラの回転アニメーション
- オブジェクトの向きのスムーズな遷移
- インバースキネマティクス（IK）での回転ブレンド
- VRコントローラーの回転トラッキング

**主要な処理内容**：
1. 基底クラスInterpolantから区間探索機能を継承
2. Quaternion.slerpFlat()静的メソッドを使用した効率的なSLERP計算
3. 複数の四元数（stride = 4の倍数）の同時補間サポート
4. 最短経路による回転補間の保証

**関連システム・外部連携**：
- Interpolant基底クラス（区間探索機能を継承）
- Quaternionクラス（slerpFlat静的メソッド）
- QuaternionKeyframeTrackクラス（補間器として使用）
- SkinnedMesh、Boneクラス（スケルタルアニメーション）

**権限による制御**：本機能は純粋な数学計算クラスであり、権限による制御は存在しない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能はUI画面に直接関連せず、内部のアニメーション補間として使用される |

## 機能種別

計算処理 / 四元数SLERP補間

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| parameterPositions | TypedArray | Yes | 補間因子（時間）の配列 | ソート済みを想定 |
| sampleValues | TypedArray | Yes | 四元数サンプル値（x,y,z,w）の配列 | 4の倍数の長さ |
| sampleSize | number | Yes | 1サンプルあたりの値の数 | 4の倍数 |
| resultBuffer | TypedArray | No | 結果格納バッファ | 省略時は自動生成 |
| i1 | number | Yes | 現在の区間インデックス | 基底クラスから渡される |
| t0 | number | Yes | 区間開始時間 | 基底クラスから渡される |
| t | number | Yes | 評価時間 | 基底クラスから渡される |
| t1 | number | Yes | 区間終了時間 | 基底クラスから渡される |

### 入力データソース

- Interpolant.evaluate()からの呼び出し
- QuaternionKeyframeTrackからのキーフレームデータ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | TypedArray | SLERP補間された四元数（x,y,z,w） |

### 出力先

- resultBuffer（内部バッファ）
- AnimationMixerを経由してオブジェクトのquaternionプロパティに適用

## 処理フロー

### 処理シーケンス

```
1. interpolate_(i1, t0, t, t1)呼び出し
   └─ 基底クラスevaluate()からの呼び出し
2. 補間係数alphaの計算
   └─ alpha = (t - t0) / (t1 - t0)
3. オフセット計算
   └─ offset = i1 * stride
4. 各四元数についてループ
   └─ Quaternion.slerpFlat()を呼び出し
5. 結果返却
   └─ resultBufferを返却
```

### フローチャート

```mermaid
flowchart TD
    A[interpolate_呼び出し] --> B[alpha計算]
    B --> C[オフセット計算]
    C --> D{各四元数ループ}
    D -->|offset < end| E[Quaternion.slerpFlat呼び出し]
    E --> F[offset += 4]
    F --> D
    D -->|完了| G[resultBuffer返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-149-01 | SLERP補間 | 球面線形補間を使用 | 常時 |
| BR-149-02 | 最短経路 | 回転の最短経路を選択 | slerpFlat内部で処理 |
| BR-149-03 | stride=4 | 四元数は4成分（x,y,z,w） | 常時 |
| BR-149-04 | 単位四元数 | 入出力は正規化された四元数を想定 | 常時 |

### 計算ロジック

**補間係数計算**：
```javascript
alpha = (t - t0) / (t1 - t0)
```

**SLERP補間（Quaternion.slerpFlat内部）**：
```javascript
// 内積計算（コサイン）
cosHalfTheta = x0*x1 + y0*y1 + z0*z1 + w0*w1

// 最短経路の選択（内積が負の場合、q1を反転）
if (cosHalfTheta < 0) {
    q1 = -q1
    cosHalfTheta = -cosHalfTheta
}

// 角度から補間重みを計算
halfTheta = Math.acos(cosHalfTheta)
sinHalfTheta = Math.sqrt(1 - cosHalfTheta * cosHalfTheta)

ratioA = Math.sin((1 - t) * halfTheta) / sinHalfTheta
ratioB = Math.sin(t * halfTheta) / sinHalfTheta

// SLERP計算
result = q0 * ratioA + q1 * ratioB
```

## データベース操作仕様

### 操作別データベース影響一覧

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | - | 本クラスは特別なエラー処理を行わない |

### リトライ仕様

該当なし（同期的な計算処理のため）

## トランザクション仕様

該当なし（データベース操作を行わないため）

## パフォーマンス要件

- 補間計算はO(stride/4)の線形時間
- Quaternion.slerpFlatは配列直接操作で効率的
- 三角関数計算を含むが、slerpFlatは最適化済み

## セキュリティ考慮事項

特になし（純粋な数学計算クラス）

## 備考

- 入力四元数は正規化されていることを前提
- 180度以上の回転は最短経路が選択されるため、意図しない方向に回転する可能性
- 複数の四元数を同時に補間可能（スケルタルアニメーション対応）

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: クラス構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | QuaternionLinearInterpolant.js | `src/math/interpolants/QuaternionLinearInterpolant.js` | インポートとクラス定義（1-9行目） |
| 1-2 | QuaternionLinearInterpolant.js | `src/math/interpolants/QuaternionLinearInterpolant.js` | コンストラクタ（18-22行目） |

**読解のコツ**: QuaternionクラスのslerpFlat静的メソッドを使用することで、配列上で直接SLERP計算を行う。

#### Step 2: interpolate_()メソッドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | QuaternionLinearInterpolant.js | `src/math/interpolants/QuaternionLinearInterpolant.js` | interpolate_メソッド（24-43行目） |

**主要処理フロー**:
- **26-29行目**: resultBuffer、sampleValues、strideの取得
- **31行目**: 補間係数alphaの計算
- **33行目**: 開始オフセットの計算
- **35-39行目**: 各四元数についてslerpFlat呼び出し

#### Step 3: Quaternion.slerpFlatを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Quaternion.js | `src/math/Quaternion.js` | slerpFlat静的メソッド |

**読解のコツ**: slerpFlatは配列とオフセットを直接操作し、オブジェクト生成を避けて効率化している。

### プログラム呼び出し階層図

```
Interpolant (基底クラス)
    │
    └─ QuaternionLinearInterpolant
           │
           ├─ constructor()
           │      └─ super() 呼び出し
           │
           └─ interpolate_(i1, t0, t, t1)
                  │
                  ├─ alpha計算
                  │      └─ (t - t0) / (t1 - t0)
                  │
                  └─ 各四元数ループ
                         │
                         └─ Quaternion.slerpFlat()
                                │
                                ├─ 内積計算（cosHalfTheta）
                                ├─ 最短経路選択
                                ├─ 角度計算
                                └─ SLERP計算
```

### データフロー図

```
[入力]               [処理]                    [出力]

i1, t0, t, t1 ─────▶ alpha計算 ────────────────┐
                     (t-t0)/(t1-t0)            │
                                               │
sampleValues ──────▶ オフセット計算 ───────────┤
(四元数配列)         │                         │
                     │                         ▼
                     │
                     └──▶ Quaternion.slerpFlat ─▶ resultBuffer
                          (SLERP補間)             (補間された四元数)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| QuaternionLinearInterpolant.js | `src/math/interpolants/QuaternionLinearInterpolant.js` | ソース | 四元数SLERP補間クラス本体 |
| Interpolant.js | `src/math/Interpolant.js` | ソース | 補間基底クラス |
| Quaternion.js | `src/math/Quaternion.js` | ソース | slerpFlat静的メソッド提供 |
| KeyframeTrack.js | `src/animation/KeyframeTrack.js` | ソース | 補間器を使用するトラック |
| QuaternionKeyframeTrack.js | `src/animation/tracks/QuaternionKeyframeTrack.js` | ソース | 四元数キーフレームトラック |
