# 機能設計書 147-BezierInterpolant

## 概要

本ドキュメントは、Three.jsライブラリにおけるBezierInterpolant（ベジェ曲線補間）機能の設計について記述する。BezierInterpolantは、Interpolant基底クラスを継承し、2Dコントロールポイントを持つ3次ベジェ曲線による補間を提供する。

### 本機能の処理概要

BezierInterpolantは、COLLADA/Maya形式のベジェアニメーションをサポートする補間器である。各キーフレームに明示的なイン/アウトタンジェント（接線）コントロールポイントを2D座標（時間、値）として指定することで、アニメーションカーブの形状を細かく制御できる。

**業務上の目的・背景**：3Dアニメーションツール（Maya、Blender、Cinema 4Dなど）では、アニメーターがベジェカーブを使用してアニメーションのタイミングと値の変化を精密に制御する。これらのツールからエクスポートされたアニメーションデータを正確に再現するために、BezierInterpolantはCOLLADA形式の2Dタンジェント仕様に対応している。Newton-Raphson法を使用して時間軸上の非線形な補間を解決し、オリジナルのアニメーションカーブを忠実に再現する。

**機能の利用シーン**：
- COLLADAファイルからインポートしたアニメーション
- Maya/Blenderからエクスポートしたカーブアニメーション
- カスタムイージング曲線の実装
- 時間リマッピングを伴うアニメーション
- アニメーションエディターでのベジェカーブ編集

**主要な処理内容**：
1. 基底クラスInterpolantから区間探索機能を継承
2. 2Dタンジェント（inTangents、outTangents）の読み取り
3. Newton-Raphson法による時間パラメータsの求解
4. 3次ベジェ曲線による値の補間
5. タンジェントデータがない場合の線形補間へのフォールバック

**関連システム・外部連携**：
- Interpolant基底クラス（区間探索機能を継承）
- COLLADALoader（タンジェントデータの提供元）
- KeyframeTrackクラス（補間器として使用）

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

## 関連画面

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

## 機能種別

計算処理 / ベジェ曲線補間

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| parameterPositions | TypedArray | Yes | 補間因子（時間）の配列 | ソート済みを想定 |
| sampleValues | TypedArray | Yes | サンプル値の配列 | parameterPositionsと対応 |
| sampleSize | number | Yes | 1サンプルあたりの値の数 | 正の整数 |
| settings.inTangents | Float32Array | No | インタンジェント配列 | N*S*2要素 |
| settings.outTangents | Float32Array | No | アウトタンジェント配列 | N*S*2要素 |

### タンジェントデータのレイアウト

N個のキーフレーム、S個の成分（stride）の場合：
- 各タンジェント配列は N * S * 2 個の値を持つ
- レイアウト：[k0_c0_time, k0_c0_value, k0_c1_time, k0_c1_value, ..., k1_c0_time, k1_c0_value, ...]
- 各[time, value]ペアが1つのコントロールポイントを表す

### 入力データソース

- COLLADALoaderからのアニメーションデータ
- カスタムベジェカーブエディターからのデータ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | TypedArray | ベジェ曲線補間された値 |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. interpolate_(i1, t0, t, t1)呼び出し
   └─ 基底クラスevaluate()からの呼び出し
2. タンジェントデータの確認
   ├─ タンジェントなし: 線形補間へフォールバック
   └─ タンジェントあり: ベジェ補間を実行
3. 各成分についてループ
   └─ outTangent（前キーフレーム）とinTangent（現キーフレーム）を取得
4. Newton-Raphson法でsを求解
   └─ Bx(s) = t となる s を反復計算で求める
5. ベジェY(s)を評価
   └─ 求めた s を使用して値を計算
6. 結果返却
   └─ resultBufferを返却
```

### フローチャート

```mermaid
flowchart TD
    A[interpolate_呼び出し] --> B{タンジェントデータあり?}
    B -->|No| C[線形補間]
    B -->|Yes| D[各成分ループ開始]
    C --> K[結果返却]
    D --> E[タンジェント取得]
    E --> F[初期s推定]
    F --> G[Newton-Raphson反復]
    G --> H{収束?}
    H -->|No, iter<8| I[s更新]
    I --> G
    H -->|Yes| J[ベジェY評価]
    J --> L{全成分完了?}
    L -->|No| D
    L -->|Yes| K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-147-01 | フォールバック | タンジェントなしの場合は線形補間 | inTangents/outTangentsがnull |
| BR-147-02 | Newton-Raphson | 最大8回の反復 | ベジェ補間時 |
| BR-147-03 | 収束判定 | 誤差 < 1e-10 で収束 | Newton-Raphson反復 |
| BR-147-04 | s範囲制限 | sを[0, 1]にクランプ | 各反復後 |

### 計算ロジック

**3次ベジェ曲線**：
```
B(s) = (1-s)³·P0 + 3(1-s)²s·C0 + 3(1-s)s²·C1 + s³·P1
```

**Newton-Raphson法**：
```javascript
// Bx(s) = t を解く
for (iter = 0; iter < 8; iter++) {
    // ベジェX(s)を評価
    bx = (1-s)³ * t0 + 3*(1-s)²*s * c0x + 3*(1-s)*s² * c1x + s³ * t1

    error = bx - t
    if (|error| < 1e-10) break

    // 導関数dX/ds
    dbx = 3*(1-s)² * (c0x - t0) + 6*(1-s)*s * (c1x - c0x) + 3*s² * (t1 - c1x)
    if (|dbx| < 1e-10) break

    s = s - error / dbx
    s = clamp(s, 0, 1)
}
```

**最終値の計算**：
```javascript
result[i] = (1-s)³ * v0 + 3*(1-s)²*s * c0y + 3*(1-s)*s² * c1y + s³ * v1
```

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | タンジェントデータなし | 線形補間にフォールバック |
| - | - | Newton-Raphson非収束 | 8回反復後の値を使用 |

### リトライ仕様

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

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

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

## パフォーマンス要件

- 各成分ごとに最大8回のNewton-Raphson反復
- 複雑なベジェカーブでは計算コストが線形補間より高い
- タンジェントなしの場合は線形補間と同等のパフォーマンス

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

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

## 備考

- COLLADA/Maya形式の2Dタンジェントに対応
- タンジェントの時間成分により、時間軸上の非線形なイージングが可能
- タンジェントデータがない場合は自動的に線形補間にフォールバック

---

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

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

### 推奨読解順序

#### Step 1: クラス構造とタンジェントレイアウトを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | BezierInterpolant.js | `src/math/interpolants/BezierInterpolant.js` | クラスドキュメントとタンジェントレイアウト（3-20行目） |

**読解のコツ**: タンジェントデータは[time, value]ペアの配列。各キーフレーム、各成分ごとに2要素（time, value）が必要。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | BezierInterpolant.js | `src/math/interpolants/BezierInterpolant.js` | フォールバック処理（37-50行目） |
| 2-2 | BezierInterpolant.js | `src/math/interpolants/BezierInterpolant.js` | タンジェント取得（55-68行目） |
| 2-3 | BezierInterpolant.js | `src/math/interpolants/BezierInterpolant.js` | Newton-Raphson法（74-95行目） |
| 2-4 | BezierInterpolant.js | `src/math/interpolants/BezierInterpolant.js` | ベジェY評価（98行目） |

**主要処理フロー**:
- **37-50行目**: タンジェントがない場合の線形補間フォールバック
- **61-68行目**: outTangent（前キーフレーム）とinTangent（現キーフレーム）の取得
- **71行目**: 初期s推定値（線形補間と同じ）
- **74-95行目**: Newton-Raphson反復でsを求解
- **98行目**: 求めたsでベジェY(s)を評価

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

```
Interpolant (基底クラス)
    │
    └─ BezierInterpolant
           │
           └─ interpolate_(i1, t0, t, t1)
                  │
                  ├─ タンジェント確認
                  │      │
                  │      └─ なし: 線形補間
                  │
                  └─ 各成分ループ
                         │
                         ├─ タンジェント取得
                         │      ├─ outTangent[前キーフレーム]
                         │      └─ inTangent[現キーフレーム]
                         │
                         ├─ Newton-Raphson法
                         │      ├─ Bx(s)評価
                         │      ├─ 誤差計算
                         │      ├─ dBx/ds計算
                         │      └─ s更新・クランプ
                         │
                         └─ By(s)評価
                                └─ result[i]に格納
```

### データフロー図

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

settings.inTangents
settings.outTangents ──▶ タンジェント取得 ────┐
                                               │
sampleValues ───────────▶ v0, v1 取得 ────────┤
                                               │
t0, t1 ─────────────────▶ P0, P1（端点） ─────┤
                                               │
t ──────────────────────▶ Newton-Raphson ─────┤
                         (Bx(s) = t を解く)    │
                                               ▼
                         s（ベジェパラメータ）
                                               │
                                               ▼
                         By(s)評価 ───────────▶ resultBuffer
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| BezierInterpolant.js | `src/math/interpolants/BezierInterpolant.js` | ソース | ベジェ曲線補間クラス本体 |
| Interpolant.js | `src/math/Interpolant.js` | ソース | 補間基底クラス |
| KeyframeTrack.js | `src/animation/KeyframeTrack.js` | ソース | 補間器を使用するトラック |
| COLLADALoader.js | `examples/jsm/loaders/COLLADALoader.js` | ソース | COLLADAファイルからのタンジェント読み込み |
