# 機能設計書 144-Interpolant

## 概要

本ドキュメントは、Three.jsライブラリにおけるInterpolant（補間基底クラス）機能の設計について記述する。Interpolantは、パラメトリックサンプル上での補間処理を行う抽象基底クラスであり、アニメーションシステムにおけるキーフレーム間の値の補間を提供する。

### 本機能の処理概要

Interpolantは、1次元のパラメータドメイン（通常は時間またはパス）上でサンプル値を補間するための抽象基底クラスである。Template Methodパターンを採用し、区間探索の共通ロジックを提供しつつ、実際の補間計算は派生クラスに委譲する。

**業務上の目的・背景**：3Dアニメーションでは、キーフレーム間の値を滑らかに補間する必要がある。位置、回転、スケールなど様々なプロパティに対して、線形補間、3次補間、離散補間など異なる補間方式が求められる。Interpolantは、区間探索のロジック（時間計算量O(1)の線形アクセス、O(log N)のランダムアクセス）を共通化し、補間アルゴリズムのみを派生クラスで実装できるようにすることで、コードの再利用性と拡張性を高めている。

**機能の利用シーン**：
- KeyframeTrackでのキーフレーム補間
- AnimationMixerでのアニメーション再生
- カスタム補間アルゴリズムの実装ベース
- モーションパス上の位置補間

**主要な処理内容**：
1. パラメータ位置に対する区間探索（二分探索＋線形スキャン）
2. キャッシュを活用した高速区間検索
3. 境界条件の処理（開始前、終了後）
4. サンプル値のコピーと補間計算（派生クラス実装）

**関連システム・外部連携**：
- KeyframeTrackクラス（補間器を使用）
- AnimationClipクラス（トラックの集合）
- AnimationMixerクラス（再生制御）

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

## 関連画面

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

## 機能種別

計算処理 / 補間基底クラス

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| parameterPositions | TypedArray | Yes | 補間因子（通常は時間）の配列 | ソート済みを想定 |
| sampleValues | TypedArray | Yes | サンプル値の配列 | parameterPositionsと対応 |
| sampleSize | number | Yes | 1サンプルあたりの値の数 | 正の整数 |
| resultBuffer | TypedArray | No | 結果格納バッファ | 省略時は自動生成 |
| t | number | Yes | 評価位置（時間など） | 任意の数値 |

### 入力データソース

- KeyframeTrackからのキーフレームデータ
- AnimationClipからのアニメーションデータ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| resultBuffer | TypedArray | 補間された値 |

### 出力先

- AnimationMixerを経由してオブジェクトプロパティに適用

## 処理フロー

### 処理シーケンス

```
1. evaluate(t)呼び出し
   └─ 評価位置tを受け取る
2. 区間検証（validate_interval）
   └─ キャッシュされた区間が有効かチェック
3. 区間探索（seek）
   ├─ 線形スキャン（前方/後方）
   └─ 二分探索（範囲外の場合）
4. 境界処理
   ├─ t < 開始位置: 最初のサンプルをコピー
   └─ t > 終了位置: 最後のサンプルをコピー
5. 補間計算
   └─ interpolate_()を呼び出し（派生クラス実装）
6. 結果返却
   └─ resultBufferを返却
```

### フローチャート

```mermaid
flowchart TD
    A[evaluate呼び出し] --> B{キャッシュ区間有効?}
    B -->|Yes| K[interpolate_呼び出し]
    B -->|No| C{前方スキャン?}
    C -->|Yes| D[前方線形スキャン]
    C -->|No| E{後方スキャン?}
    D --> F{区間発見?}
    E --> G[後方線形スキャン]
    G --> F
    F -->|Yes| H[キャッシュ更新]
    F -->|No| I[二分探索]
    I --> J{境界チェック}
    J -->|開始前| L[最初のサンプルコピー]
    J -->|終了後| M[最後のサンプルコピー]
    J -->|区間内| H
    H --> K
    L --> N[結果返却]
    M --> N
    K --> N
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-144-01 | 線形アクセス計算量 | 2点以下の横断でO(1) | 連続的な時間進行時 |
| BR-144-02 | ランダムアクセス計算量 | O(log N) | ジャンプ再生時 |
| BR-144-03 | 境界外処理 | 最近傍のサンプル値を返却 | t < t0 または t > tN |
| BR-144-04 | キャッシュ戦略 | 最後に評価した区間をキャッシュ | 常時 |

### 計算ロジック

**区間探索アルゴリズム**：
1. 現在のキャッシュ区間 [t0, t1] をチェック
2. t >= t1 の場合、前方に2点まで線形スキャン
3. t < t0 の場合、後方に2点まで線形スキャン
4. 線形スキャンで見つからない場合、二分探索
5. 見つかった区間をキャッシュ

**二分探索**：
```javascript
while (i1 < right) {
    const mid = (i1 + right) >>> 1;
    if (t < pp[mid]) {
        right = mid;
    } else {
        i1 = mid + 1;
    }
}
```

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Error | interpolate_()が未実装 | "call to abstract method"エラー |

### リトライ仕様

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

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

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

## パフォーマンス要件

- 連続的な時間進行：O(1)の定数時間
- ランダムアクセス：O(log N)の対数時間
- キャッシュにより同一区間の再評価を高速化

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

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

## 備考

- Template Methodパターンを採用
- 派生クラスはinterpolate_()メソッドを実装する必要がある
- intervalChanged_()はオプションのフック（CubicInterpolantで使用）
- 参考：http://www.oodesign.com/template-method-pattern.html

---

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

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

### 推奨読解順序

#### Step 1: クラス構造とプロパティを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Interpolant.js | `src/math/Interpolant.js` | コンストラクタとプロパティ（30-84行目） |

**読解のコツ**: parameterPositionsは時間（または他のパラメータ）、sampleValuesは補間対象の値、valueSizeは1サンプルあたりの要素数。

**主要処理フロー**:
- **37行目**: parameterPositions - 補間因子配列
- **46行目**: _cachedIndex - キャッシュされた区間インデックス
- **53行目**: resultBuffer - 補間結果格納バッファ
- **67行目**: valueSize - サンプルサイズ

#### Step 2: evaluate()メソッドの区間探索を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Interpolant.js | `src/math/Interpolant.js` | evaluate()メソッド（92-250行目） |

**主要処理フロー**:
- **94-97行目**: キャッシュ区間の取得
- **111-145行目**: 前方線形スキャン（t >= t1の場合）
- **149-194行目**: 後方線形スキャン（t < t0の場合）
- **204-218行目**: 二分探索
- **248行目**: interpolate_()呼び出し

#### Step 3: 補助メソッドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Interpolant.js | `src/math/Interpolant.js` | copySampleValue_()（269-286行目） |
| 3-2 | Interpolant.js | `src/math/Interpolant.js` | interpolate_()抽象メソッド（298-303行目） |
| 3-3 | Interpolant.js | `src/math/Interpolant.js` | intervalChanged_()フック（312-316行目） |

**主要処理フロー**:
- **269-286行目**: copySampleValue_ - サンプル値をresultBufferにコピー
- **300行目**: interpolate_ - 抽象メソッド、派生クラスで実装必須
- **312-316行目**: intervalChanged_ - 区間変更時のオプションフック

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

```
Interpolant (抽象基底クラス)
    │
    ├─ コンストラクタ
    │      └─ プロパティ初期化
    │
    ├─ 公開メソッド
    │      └─ evaluate(t)
    │             │
    │             ├─ validate_interval
    │             │      ├─ forward_scan (前方線形スキャン)
    │             │      ├─ backward_scan (後方線形スキャン)
    │             │      └─ binary_search (二分探索)
    │             │
    │             ├─ copySampleValue_() (境界外の場合)
    │             │
    │             ├─ intervalChanged_() (区間変更時)
    │             │
    │             └─ interpolate_() (派生クラス実装)
    │
    └─ 派生クラス
           ├─ LinearInterpolant
           ├─ CubicInterpolant
           ├─ DiscreteInterpolant
           ├─ BezierInterpolant
           └─ QuaternionLinearInterpolant
```

### データフロー図

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

parameterPositions
(時間配列) ─────────┐
                    │
sampleValues   ─────┼──▶ evaluate(t) ─────────▶ resultBuffer
(値配列)            │         │                 (補間された値)
                    │         │
t (評価位置) ───────┘         │
                              │
                    ┌─────────┴─────────┐
                    │                   │
              区間探索              interpolate_
              (O(1)/O(logN))       (派生クラス)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Interpolant.js | `src/math/Interpolant.js` | ソース | 補間基底クラス本体 |
| LinearInterpolant.js | `src/math/interpolants/LinearInterpolant.js` | ソース | 線形補間派生クラス |
| CubicInterpolant.js | `src/math/interpolants/CubicInterpolant.js` | ソース | 3次補間派生クラス |
| DiscreteInterpolant.js | `src/math/interpolants/DiscreteInterpolant.js` | ソース | 離散補間派生クラス |
| QuaternionLinearInterpolant.js | `src/math/interpolants/QuaternionLinearInterpolant.js` | ソース | 四元数SLERP派生クラス |
| KeyframeTrack.js | `src/animation/KeyframeTrack.js` | ソース | 補間器を使用するトラック |
