# 機能設計書 150-ArrowHelper

## 概要

本ドキュメントは、Three.jsライブラリにおけるArrowHelper（矢印ヘルパー）機能の設計について記述する。ArrowHelperは、3D空間で方向を視覚化するための矢印オブジェクトを提供し、デバッグや可視化目的で使用される。

### 本機能の処理概要

ArrowHelperは、Object3Dを継承した3Dオブジェクトで、線分（シャフト）と円錐（ヘッド）から構成される矢印形状を提供する。法線ベクトル、速度ベクトル、力の方向など、3D空間における方向と大きさを視覚的に表現するのに適している。

**業務上の目的・背景**：3D開発において、ベクトルの方向や大きさを視覚的に確認することは非常に重要である。法線ベクトルのデバッグ、物理演算の力の可視化、カメラの視線方向の表示など、様々なシーンで矢印による可視化が必要となる。ArrowHelperは、これらのニーズに対応するために、方向、原点、長さ、色を簡単に設定できるヘルパーオブジェクトを提供する。ジオメトリは共有されるため、多数の矢印を効率的に描画できる。

**機能の利用シーン**：
- 法線ベクトルのデバッグ表示
- 物理シミュレーションでの力の可視化
- カメラの視線方向の表示
- オブジェクトの移動方向の表示
- レイキャスティングの結果の可視化
- 座標軸の表示補助

**主要な処理内容**：
1. 線分（Line）とコーン（Mesh）の組み合わせで矢印を構成
2. 方向ベクトルに基づく四元数回転の設定
3. 長さに応じたスケーリング
4. 色の動的変更
5. ジオメトリの共有による効率化

**関連システム・外部連携**：
- Object3Dクラス（基底クラス）
- BufferGeometry、ConeGeometry（形状定義）
- LineBasicMaterial、MeshBasicMaterial（マテリアル）
- Line、Mesh（描画オブジェクト）
- Vector3（方向・位置）

**権限による制御**：本機能はヘルパーオブジェクトであり、権限による制御は存在しない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能はデバッグ・可視化用ヘルパーとして各種画面で使用可能 |

## 機能種別

可視化 / デバッグヘルパー

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| dir | Vector3 | No | 方向ベクトル（正規化済み） | デフォルト(0,0,1) |
| origin | Vector3 | No | 矢印の始点 | デフォルト(0,0,0) |
| length | number | No | 矢印の長さ | デフォルト1 |
| color | number/Color/string | No | 矢印の色 | デフォルト0xffff00（黄色） |
| headLength | number | No | 矢尻の長さ | デフォルトlength*0.2 |
| headWidth | number | No | 矢尻の幅 | デフォルトheadLength*0.2 |

### 入力データソース

- ユーザーコードからの直接指定
- 計算されたベクトル値

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ArrowHelper | Object3D | 矢印オブジェクト（シーンに追加可能） |
| line | Line | 矢印のシャフト部分 |
| cone | Mesh | 矢印のヘッド部分 |

### 出力先

- Scene（シーングラフに追加）

## 処理フロー

### 処理シーケンス

```
1. コンストラクタ呼び出し
   └─ 引数を受け取りデフォルト値を設定
2. ジオメトリの初期化（初回のみ）
   ├─ _lineGeometry: 2点の線分ジオメトリ
   └─ _coneGeometry: 円錐ジオメトリ（位置調整済み）
3. 位置の設定
   └─ this.position.copy(origin)
4. 線分（line）の作成
   └─ LineBasicMaterialで線を作成
5. コーン（cone）の作成
   └─ MeshBasicMaterialでメッシュを作成
6. 方向の設定
   └─ setDirection(dir)で四元数を設定
7. 長さの設定
   └─ setLength(length, headLength, headWidth)でスケーリング
```

### フローチャート

```mermaid
flowchart TD
    A[コンストラクタ呼び出し] --> B{ジオメトリ初期化済み?}
    B -->|No| C[_lineGeometry作成]
    C --> D[_coneGeometry作成]
    B -->|Yes| E[位置設定]
    D --> E
    E --> F[Line作成・追加]
    F --> G[Mesh作成・追加]
    G --> H[setDirection呼び出し]
    H --> I[setLength呼び出し]
    I --> J[完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-150-01 | ジオメトリ共有 | 全ArrowHelperで_lineGeometryと_coneGeometryを共有 | 常時 |
| BR-150-02 | デフォルト方向 | Y軸正方向（0,1,0）を基準に回転 | setDirection時 |
| BR-150-03 | 矢尻位置 | headLengthを除いた位置にlineをスケーリング | setLength時 |
| BR-150-04 | toneMapped無効 | マテリアルのtoneMappedをfalseに設定 | マテリアル作成時 |

### 計算ロジック

**方向設定（setDirection）**：
```javascript
if (dir.y > 0.99999) {
    // ほぼ真上: 単位四元数
    this.quaternion.set(0, 0, 0, 1);
} else if (dir.y < -0.99999) {
    // ほぼ真下: X軸周り180度回転
    this.quaternion.set(1, 0, 0, 0);
} else {
    // 一般的なケース: 軸角度から四元数を計算
    _axis.set(dir.z, 0, -dir.x).normalize();
    radians = Math.acos(dir.y);
    this.quaternion.setFromAxisAngle(_axis, radians);
}
```

**長さ設定（setLength）**：
```javascript
// lineのスケーリング（headLengthを除く）
this.line.scale.set(1, Math.max(0.0001, length - headLength), 1);

// coneのスケーリングと位置
this.cone.scale.set(headWidth, headLength, headWidth);
this.cone.position.y = length;
```

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

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

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

## エラー処理

### エラーケース一覧

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

### リトライ仕様

該当なし

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

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

## パフォーマンス要件

- ジオメトリ共有によりメモリ使用量を削減
- matrixAutoUpdate = falseで自動更新を無効化
- 手動でupdateMatrix()を呼び出し

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

特になし（ヘルパーオブジェクト）

## 備考

- dispose()メソッドでリソースを解放可能
- copy()メソッドでArrowHelperを複製可能
- toneMapped: falseにより、ポストプロセスの影響を受けない一定の色を維持

---

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

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

### 推奨読解順序

#### Step 1: インポートと共有ジオメトリを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ArrowHelper.js | `src/helpers/ArrowHelper.js` | インポート文（1-9行目） |
| 1-2 | ArrowHelper.js | `src/helpers/ArrowHelper.js` | モジュールレベル変数（11-12行目） |

**読解のコツ**: _lineGeometryと_coneGeometryはモジュールレベルで定義され、全インスタンスで共有される。

#### Step 2: コンストラクタを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ArrowHelper.js | `src/helpers/ArrowHelper.js` | コンストラクタ（45-84行目） |

**主要処理フロー**:
- **51-59行目**: ジオメトリの遅延初期化
- **61行目**: 原点位置の設定
- **68行目**: Line作成とmatrixAutoUpdate無効化
- **77行目**: Mesh作成とmatrixAutoUpdate無効化
- **81-82行目**: setDirectionとsetLengthの呼び出し

#### Step 3: 操作メソッドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ArrowHelper.js | `src/helpers/ArrowHelper.js` | setDirection（91-113行目） |
| 3-2 | ArrowHelper.js | `src/helpers/ArrowHelper.js` | setLength（122-131行目） |
| 3-3 | ArrowHelper.js | `src/helpers/ArrowHelper.js` | setColor（138-142行目） |

**主要処理フロー**:
- **95-101行目**: 特殊ケース（真上/真下）の処理
- **103-109行目**: 一般ケースの軸角度計算
- **124行目**: lineスケーリング（#17458対応で最小値0.0001）
- **127-128行目**: coneスケーリングと位置

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

```
Object3D (基底クラス)
    │
    └─ ArrowHelper
           │
           ├─ constructor()
           │      │
           │      ├─ ジオメトリ初期化（初回のみ）
           │      │      ├─ _lineGeometry (BufferGeometry)
           │      │      └─ _coneGeometry (ConeGeometry)
           │      │
           │      ├─ Line作成
           │      │      └─ LineBasicMaterial
           │      │
           │      ├─ Mesh作成
           │      │      └─ MeshBasicMaterial
           │      │
           │      ├─ setDirection()
           │      │      └─ quaternion.setFromAxisAngle()
           │      │
           │      └─ setLength()
           │             ├─ line.scale.set()
           │             └─ cone.scale.set() / cone.position.y
           │
           ├─ setDirection(dir)
           │      └─ quaternion設定
           │
           ├─ setLength(length, headLength, headWidth)
           │      └─ line/coneのスケーリング
           │
           ├─ setColor(color)
           │      └─ material.color.set()
           │
           ├─ copy(source)
           │
           └─ dispose()
                  └─ geometry/materialの解放
```

### データフロー図

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

dir (Vector3) ─────▶ setDirection ────────────▶ this.quaternion
                     (四元数計算)

origin (Vector3) ──▶ position.copy ───────────▶ this.position

length,
headLength, ───────▶ setLength ───────────────▶ line.scale
headWidth            │                          cone.scale
                     │                          cone.position.y
                     └─ updateMatrix()

color ─────────────▶ setColor ────────────────▶ line.material.color
                                                cone.material.color
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ArrowHelper.js | `src/helpers/ArrowHelper.js` | ソース | 矢印ヘルパークラス本体 |
| Object3D.js | `src/core/Object3D.js` | ソース | 基底クラス |
| BufferAttribute.js | `src/core/BufferAttribute.js` | ソース | 線分ジオメトリの頂点データ |
| BufferGeometry.js | `src/core/BufferGeometry.js` | ソース | 線分ジオメトリ |
| ConeGeometry.js | `src/geometries/ConeGeometry.js` | ソース | 矢尻のジオメトリ |
| MeshBasicMaterial.js | `src/materials/MeshBasicMaterial.js` | ソース | 矢尻のマテリアル |
| LineBasicMaterial.js | `src/materials/LineBasicMaterial.js` | ソース | シャフトのマテリアル |
| Line.js | `src/objects/Line.js` | ソース | 線分オブジェクト |
| Mesh.js | `src/objects/Mesh.js` | ソース | メッシュオブジェクト |
| Vector3.js | `src/math/Vector3.js` | ソース | 方向・位置ベクトル |
