# 機能設計書 80-LineLoop

## 概要

本ドキュメントは、Three.jsライブラリにおけるLineLoop（閉じた線）機能の設計を記述する。LineLoopは連続した頂点を直線で結び、最後の頂点と最初の頂点を接続して閉じたループを形成する3Dオブジェクトである。

### 本機能の処理概要

LineLoopは、Lineクラスを継承し、頂点データの最後と最初を自動的に接続して閉じた線（ループ）を描画する。Lineが開いた線（LINE_STRIP）を描画するのに対し、LineLoopは閉じた線（LINE_LOOP）を描画する。多角形の輪郭線、閉じたパス、境界線などの描画に使用される。

**業務上の目的・背景**：3Dグラフィックスにおいて、閉じた形状の輪郭線を描画する場面は多い。多角形の境界線、円形や楕円形のパス、閉じた曲線などでは、最後の頂点と最初の頂点を明示的に接続する必要なく、自動的に閉じた線を描画できる機能が求められる。LineLoopは、このような用途に特化したクラスを提供する。

**機能の利用シーン**：多角形の輪郭線描画、閉じたパスの可視化、円形・楕円形の近似描画、境界ボックスの輪郭線、選択領域の表示、デバッグ用の閉じた補助線。

**主要な処理内容**：
1. 頂点を連続した線で接続し、最後の頂点と最初の頂点を自動接続
2. Lineクラスの機能を継承（レイキャスト、モーフターゲット等）
3. レイキャストで最終-最初の線分も交差判定対象

**関連システム・外部連携**：WebGLRenderer/WebGPURenderer、LineBasicMaterial、LineDashedMaterial。

**権限による制御**：特になし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 画面機能マッピングに登録なし |

## 機能種別

3Dオブジェクト生成 / 閉じた線描画

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| geometry | BufferGeometry | No | 線のジオメトリ | BufferGeometry型 |
| material | Material/Array<Material> | No | 線のマテリアル | Material型または配列 |

### 入力データソース

JavaScriptコードからのコンストラクタ呼び出し。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| isLineLoop | boolean | 型識別フラグ（常にtrue） |
| type | string | オブジェクト種別（'LineLoop'） |
| geometry | BufferGeometry | 線のジオメトリ（継承） |
| material | Material/Array<Material> | 線のマテリアル（継承） |

### 出力先

3Dシーングラフ、WebGLレンダリングパイプライン

## 処理フロー

### 処理シーケンス

```
1. コンストラクタ呼び出し
   └─ Lineの初期化
   └─ isLineLoop = true
   └─ type = 'LineLoop'
2. 描画時：最後の頂点と最初の頂点を自動接続
3. raycast()：最終-最初の線分も交差判定対象に含む
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[Lineコンストラクタ]
    B --> C[isLineLoop = true]
    C --> D[type = 'LineLoop']
    D --> E[終了]

    F[raycast] --> G[Lineのraycast処理]
    G --> H{isLineLoop?}
    H -->|Yes| I[最終頂点-最初の頂点も交差判定]
    H -->|No| J[終了]
    I --> J
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-80-1 | 自動クローズ | 最後の頂点と最初の頂点を自動的に接続 | 常時 |
| BR-80-2 | ループ交差判定 | レイキャストで最終-最初の線分も交差判定 | raycast時 |
| BR-80-3 | 継承動作 | Lineの全機能（computeLineDistances等）を継承 | 常時 |

### 計算ロジック

**レイキャスト時のループ処理（Lineクラス内）**：
```javascript
if (this.isLineLoop) {
    // インデックスありの場合
    const a = index.getX(end - 1);
    const b = index.getX(start);
    // 最後の頂点と最初の頂点を接続して交差判定

    // インデックスなしの場合
    const intersect = checkIntersection(this, raycaster, _ray, localThresholdSq, end - 1, start, end - 1);
}
```

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

データベース操作なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | - | 特にエラーケースなし |

### リトライ仕様

該当なし。

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

該当なし。

## パフォーマンス要件

- GL_LINE_LOOP相当の描画で効率的に処理される
- 頂点数に比例して処理時間が増加
- 最終-最初の接続は描画時に自動処理されるため追加コストは最小限

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

特になし。

## 備考

- LineLoopはGL_LINE_LOOP相当の描画を行う
- 連続した開いた線を描画する場合はLineを使用
- 独立した複数の線分を描画する場合はLineSegmentsを使用
- 閉じたループを形成するため、頂点数3以上が推奨される
- computeLineDistancesはLineから継承（破線描画はLine同様に機能）

---

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

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

### 推奨読解順序

#### Step 1: データ構造を理解する

LineLoopはLineを継承しているため、まずLineの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Line.js | `src/objects/Line.js` | 基底クラスの構造 |

**読解のコツ**: LineLoopはLineのほぼすべての機能を継承し、typeとisLineLoopフラグのみを設定する。描画とレイキャストの差異は親クラスLineのisLineLoop判定によって実現される。

#### Step 2: エントリーポイントを理解する

LineLoopクラスの構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | LineLoop.js | `src/objects/LineLoop.js` | クラス全体の構造 |

**主要処理フロー**:
1. **18-20行目**: コンストラクタでLineを初期化
2. **29行目**: isLineLoopフラグの設定
3. **31行目**: typeを'LineLoop'に設定

#### Step 3: ループ処理を理解する

Lineクラス内のisLineLoop判定処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Line.js | `src/objects/Line.js` | raycast()内のisLineLoop判定（211-224行目、243-253行目） |

**主要処理フロー**:
- **211行目**: インデックス付きジオメトリでのループ処理
- **213-214行目**: 最後のインデックスと最初のインデックスを取得
- **243行目**: 非インデックスジオメトリでのループ処理
- **245行目**: checkIntersection()で最終-最初の線分を交差判定

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

```
LineLoop
    │
    ├─ extends Line
    │      │
    │      ├─ extends Object3D
    │      │      └─ extends EventDispatcher
    │      │
    │      ├─ raycast() - isLineLoopでループ処理
    │      │      └─ 211-224行目: 最終頂点-最初の頂点を交差判定
    │      │      └─ 243-253行目: 非インデックス時のループ処理
    │      │
    │      ├─ computeLineDistances() - 破線用距離計算（継承）
    │      └─ updateMorphTargets() - モーフターゲット更新（継承）
    │
    └─ コンストラクタ
           └─ isLineLoop = true
           └─ type = 'LineLoop'
```

### データフロー図

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

geometry (引数) ──────────────▶ Lineコンストラクタ ─────────────▶ this.geometry
material (引数) ──────────────▶ Lineコンストラクタ ─────────────▶ this.material

描画時
頂点データ
[0,1,2,...,N-1] ──────────────▶ GL_LINE_LOOP描画 ───────────────▶ 閉じた線
                               (N-1→0を自動接続)

raycast時
最終頂点(N-1)
最初の頂点(0) ────────────────▶ checkIntersection ──────────────▶ intersects[]
                               (追加の交差判定)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| LineLoop.js | `src/objects/LineLoop.js` | ソース | 閉じた線クラス |
| Line.js | `src/objects/Line.js` | ソース | 基底クラス |
| Object3D.js | `src/core/Object3D.js` | ソース | オブジェクト基底クラス |
| BufferGeometry.js | `src/core/BufferGeometry.js` | ソース | ジオメトリ |
| LineBasicMaterial.js | `src/materials/LineBasicMaterial.js` | ソース | 基本線マテリアル |
| LineDashedMaterial.js | `src/materials/LineDashedMaterial.js` | ソース | 破線マテリアル |
