# 機能設計書 146-CubicInterpolant

## 概要

本ドキュメントは、Three.jsライブラリにおけるCubicInterpolant（3次補間）機能の設計について記述する。CubicInterpolantは、Interpolant基底クラスを継承し、隣接するサンプル点の傾きを考慮した滑らかな3次スプライン補間を提供する。

### 本機能の処理概要

CubicInterpolantは、エルミート構造に基づく高速かつシンプルな3次スプライン補間器である。各サンプル点での1次微分（傾き）を隣接点間の線形傾きから自動計算し、C1連続性（傾きの連続性）を保証する滑らかな補間曲線を生成する。

**業務上の目的・背景**：線形補間では速度変化が不連続になり、アニメーションが「カクカク」した印象を与えることがある。3次補間は、各サンプル点で傾きが連続するため、より自然で滑らかな動きを実現できる。特にカメラパス、キャラクターモーション、UIアニメーションなど、視覚的な滑らかさが重要なシーンで使用される。また、端点での挙動（ZeroCurvatureEnding、ZeroSlopeEnding、WrapAroundEnding）をカスタマイズできるため、ループアニメーションや自然な開始/終了を表現できる。

**機能の利用シーン**：
- カメラパスアニメーション
- キャラクターのスケルタルアニメーション
- 滑らかなUIトランジション
- モーフターゲットアニメーション
- カーブエディターでのスプライン補間

**主要な処理内容**：
1. 基底クラスInterpolantから区間探索機能を継承
2. intervalChanged_()で前後のサンプル点の重みとオフセットを計算
3. 4点を使用した3次多項式補間の実行
4. 端点処理（ZeroCurvatureEnding、ZeroSlopeEnding、WrapAroundEnding）

**関連システム・外部連携**：
- Interpolant基底クラス（区間探索機能を継承）
- KeyframeTrackクラス（補間器として使用）
- constants.js（端点挙動の定数）

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

## 関連画面

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

## 機能種別

計算処理 / 3次スプライン補間

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| parameterPositions | TypedArray | Yes | 補間因子（時間）の配列 | ソート済みを想定 |
| sampleValues | TypedArray | Yes | サンプル値の配列 | parameterPositionsと対応 |
| sampleSize | number | Yes | 1サンプルあたりの値の数 | 正の整数 |
| resultBuffer | TypedArray | No | 結果格納バッファ | 省略時は自動生成 |
| settings.endingStart | number | No | 開始端点の挙動 | ZeroCurvatureEnding（デフォルト） |
| settings.endingEnd | number | No | 終了端点の挙動 | ZeroCurvatureEnding（デフォルト） |

### 入力データソース

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

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | TypedArray | 3次スプライン補間された値 |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. evaluate(t)呼び出し（基底クラス）
   └─ 区間探索を実行
2. intervalChanged_(i1, t0, t1)呼び出し
   └─ 前後のサンプル点の重みとオフセットを計算
3. 端点処理
   ├─ ZeroCurvatureEnding: 自然スプライン（f''(t) = 0）
   ├─ ZeroSlopeEnding: 傾きゼロ（f'(t) = 0）
   └─ WrapAroundEnding: ループ接続
4. interpolate_(i1, t0, t, t1)呼び出し
   └─ 4点の重み付き和を計算
5. 結果返却
   └─ resultBufferを返却
```

### フローチャート

```mermaid
flowchart TD
    A[evaluate呼び出し] --> B[区間探索]
    B --> C{区間変更?}
    C -->|Yes| D[intervalChanged_呼び出し]
    C -->|No| G[interpolate_呼び出し]
    D --> E{前サンプル存在?}
    E -->|No| F[端点処理（開始）]
    E -->|Yes| H{後サンプル存在?}
    F --> H
    H -->|No| I[端点処理（終了）]
    H -->|Yes| J[重み・オフセット計算]
    I --> J
    J --> G
    G --> K[4点の重み付き和計算]
    K --> L[結果返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-146-01 | ZeroCurvatureEnding | f''(t) = 0（自然スプライン） | デフォルト端点処理 |
| BR-146-02 | ZeroSlopeEnding | f'(t) = 0（傾きゼロ） | 静止開始/終了時 |
| BR-146-03 | WrapAroundEnding | ループの反対端を使用 | ループアニメーション |
| BR-146-04 | 4点補間 | 前々点、前点、現点、次点を使用 | 常時 |

### 計算ロジック

**重み計算（intervalChanged_）**：
```javascript
halfDt = (t1 - t0) * 0.5
_weightPrev = halfDt / (t0 - tPrev)
_weightNext = halfDt / (tNext - t1)
```

**3次補間（interpolate_）**：
```javascript
p = (t - t0) / (t1 - t0)
pp = p * p
ppp = pp * p

sP = -wP * ppp + 2 * wP * pp - wP * p
s0 = (1 + wP) * ppp + (-1.5 - 2 * wP) * pp + (-0.5 + wP) * p + 1
s1 = (-1 - wN) * ppp + (1.5 + wN) * pp + 0.5 * p
sN = wN * ppp - wN * pp

result[i] = sP * values[oP + i] + s0 * values[o0 + i] + s1 * values[o1 + i] + sN * values[oN + i]
```

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

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

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

## エラー処理

### エラーケース一覧

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

### リトライ仕様

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

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

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

## パフォーマンス要件

- 補間計算はO(stride)の線形時間
- intervalChanged_は区間変更時のみ呼び出し
- 多項式係数は効率的に計算

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

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

## 備考

- エルミート補間に基づくが、制御点を明示的に指定せず自動計算
- C1連続性を保証（傾きが連続）
- C2連続性（曲率の連続性）は保証されない
- 端点挙動のカスタマイズでループや自然な開始/終了を表現可能

---

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

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

### 推奨読解順序

#### Step 1: クラス構造と初期化を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | CubicInterpolant.js | `src/math/interpolants/CubicInterpolant.js` | インポートと定数（1-2行目） |
| 1-2 | CubicInterpolant.js | `src/math/interpolants/CubicInterpolant.js` | コンストラクタとDefaultSettings_（23-39行目） |

**読解のコツ**: _weightPrev、_weightNext、_offsetPrev、_offsetNextは区間変更時に計算される一時変数。DefaultSettings_は端点挙動のデフォルト設定。

**主要処理フロー**:
- **27-30行目**: 一時変数の初期化（-0で初期化）
- **32-37行目**: DefaultSettings_で端点挙動をZeroCurvatureEndingに設定

#### Step 2: intervalChanged_()で端点処理を理解する

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

**主要処理フロー**:
- **43-48行目**: 前後のサンプルインデックスと時間を取得
- **50-77行目**: 前サンプルが存在しない場合の端点処理
  - **54-58行目**: ZeroSlopeEnding - 傾きゼロ
  - **62-66行目**: WrapAroundEnding - ループ接続
  - **70-74行目**: ZeroCurvatureEnding - 自然スプライン
- **80-107行目**: 後サンプルが存在しない場合の端点処理
- **110-116行目**: 重みとオフセットの計算

#### Step 3: interpolate_()で3次補間を理解する

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

**主要処理フロー**:
- **122-128行目**: 必要な変数の取得
- **130-132行目**: p、pp、pppの計算
- **136-139行目**: 4点の係数sP、s0、s1、sNの計算
- **143-150行目**: 各成分の重み付き和

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

```
Interpolant (基底クラス)
    │
    └─ CubicInterpolant
           │
           ├─ constructor()
           │      ├─ super() 呼び出し
           │      ├─ 一時変数初期化
           │      └─ DefaultSettings_ 設定
           │
           ├─ intervalChanged_(i1, t0, t1)
           │      │
           │      ├─ 前サンプル処理
           │      │      ├─ ZeroSlopeEnding
           │      │      ├─ WrapAroundEnding
           │      │      └─ ZeroCurvatureEnding
           │      │
           │      ├─ 後サンプル処理
           │      │      ├─ ZeroSlopeEnding
           │      │      ├─ WrapAroundEnding
           │      │      └─ ZeroCurvatureEnding
           │      │
           │      └─ 重み・オフセット計算
           │
           └─ interpolate_(i1, t0, t, t1)
                  │
                  ├─ p計算（正規化パラメータ）
                  ├─ 多項式係数計算
                  └─ 4点の重み付き和
```

### データフロー図

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

区間変更通知 ──────▶ intervalChanged_
                     │
                     ├─ 端点処理（開始/終了）
                     │
                     └─ 重み・オフセット計算
                            │
                            ▼
                     _weightPrev, _weightNext
                     _offsetPrev, _offsetNext

i1, t0, t, t1 ─────▶ interpolate_
                     │
                     ├─ p, pp, ppp 計算
                     │
                     ├─ sP, s0, s1, sN 計算
                     │
                     └─ 4点重み付き和 ────────▶ resultBuffer
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| CubicInterpolant.js | `src/math/interpolants/CubicInterpolant.js` | ソース | 3次スプライン補間クラス本体 |
| Interpolant.js | `src/math/Interpolant.js` | ソース | 補間基底クラス |
| constants.js | `src/constants.js` | ソース | 端点挙動定数（ZeroCurvatureEnding等） |
| KeyframeTrack.js | `src/animation/KeyframeTrack.js` | ソース | 補間器を使用するトラック |
