# 機能設計書 136-Line3

## 概要

本ドキュメントは、Three.jsの数学ライブラリにおける3D線分を表現するLine3クラスの機能設計書である。

### 本機能の処理概要

Line3クラスは、3D空間における有限の線分を表現するためのクラスである。始点（start）と終点（end）の2つのVector3によって線分を定義し、点との最近点計算、線分同士の最短距離計算、平面との交差判定などに使用される。Rayクラス（半直線）とは異なり、有限の長さを持つ線分を表現する。

**業務上の目的・背景**：3Dグラフィックスにおいて、線分は辺の表現、衝突検出、最短経路計算、スケルトンのボーン表現など、多くの場面で使用される。Line3クラスは、これらの処理に必要な線分の数学的表現と、各種計算機能を提供する。

**機能の利用シーン**：
- 平面との交点計算（Plane.intersectLineで使用）
- ポリゴンの辺の表現
- 衝突検出での最近点計算
- 線分同士の最短距離計算
- パス補間での区間表現
- ワイヤーフレーム描画の基礎

**主要な処理内容**：
1. 線分の生成と初期化（始点と終点の設定）
2. 中心点・長さ・デルタベクトルの計算
3. 点との最近点計算（クランプ有無指定可能）
4. 線分同士の最短距離計算
5. Matrix4による変換

**関連システム・外部連携**：Plane、Ray、Vector3などと連携。

**権限による制御**：なし（純粋な数学ユーティリティクラス）

## 関連画面

本機能は数学ユーティリティであり、直接的な画面との関連はない。

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 内部計算処理として使用 |

## 機能種別

計算処理 / ジオメトリ演算

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| start | Vector3 | No | 線分の始点 | デフォルト: (0, 0, 0) |
| end | Vector3 | No | 線分の終点 | デフォルト: (0, 0, 0) |

### 入力データソース

コンストラクタ引数またはメソッド呼び出しによる直接設定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| start | Vector3 | 線分の始点 |
| end | Vector3 | 線分の終点 |

### 出力先

メモリ上のオブジェクトとして保持

## 処理フロー

### 処理シーケンス

```
1. 線分の初期化
   └─ start=(0,0,0), end=(0,0,0)で初期化（長さ0の線分）
2. 線分の設定
   └─ set/copy: 始点と終点を設定
3. プロパティ計算
   ├─ getCenter: 中央点を計算
   ├─ delta: 終点-始点のベクトル
   ├─ distance: 線分の長さ
   └─ distanceSq: 長さの二乗
4. 点との関係計算
   ├─ closestPointToPointParameter: 最近点のパラメータ（0-1）
   └─ closestPointToPoint: 最近点の座標
5. 線分同士の計算
   └─ distanceSqToLine3: 2線分間の最短距離
6. 変換
   └─ applyMatrix4: 行列変換
```

### フローチャート

```mermaid
flowchart TD
    A[Line3インスタンス生成] --> B[start/endを設定]
    B --> C[線分確定]
    C --> D{操作種別}
    D -->|プロパティ取得| E[getCenter/delta/distance]
    D -->|点との計算| F[closestPointToPoint]
    F --> F1{clampToLine?}
    F1 -->|Yes| F2[パラメータを0-1にクランプ]
    F1 -->|No| F3[直線上の最近点]
    D -->|線分同士| G[distanceSqToLine3]
    D -->|補間| H[at/t/]
    D -->|変換| I[applyMatrix4]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | パラメトリック表現 | 線分上の点 = start + t * (end - start)（0 <= t <= 1） | at()メソッド |
| BR-002 | クランプ | clampToLine=trueでパラメータを[0,1]に制限 | closestPointToPoint |
| BR-003 | 縮退線分 | start == endの場合、長さ0の線分（点） | distance() = 0 |

### 計算ロジック

**中央点の計算**:
```javascript
center = (start + end) * 0.5
```

**デルタベクトル**:
```javascript
delta = end - start
```

**線分の長さ**:
```javascript
distance = length(end - start)
```

**最近点パラメータの計算**:
```javascript
startP = point - start
startEnd = end - start
t = dot(startEnd, startP) / dot(startEnd, startEnd)
if (clampToLine) t = clamp(t, 0, 1)
```

**線分上の点**:
```javascript
point = start + delta * t  // 0 <= t <= 1
```

**2線分の最短距離（Ericsonアルゴリズム）**:
```javascript
// "Real-Time Collision Detection" by Christer Ericson, chapter 5.1.9
d1 = q1 - p1  // 線分S1の方向ベクトル
d2 = q2 - p2  // 線分S2の方向ベクトル
r = p1 - p2
a = dot(d1, d1), e = dot(d2, d2), f = dot(d2, r)
// 縮退ケース（点になっている）の処理
// 非縮退ケースの一般解
s = clamp((b*f - c*e) / denom, 0, 1)
t = (b*s + f) / e
// tが[0,1]外の場合の再計算
```

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

該当なし（純粋な計算処理クラス）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 縮退線分 | start == end（長さ0） | 特別な処理（点として扱う） |
| - | ゼロ除算 | closestPointToPointParameterで長さ0 | EPSILON比較で回避 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- 基本メソッドはO(1)の計算量
- メモリ使用量: Vector3 x 2 = 48バイト程度

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

該当なし（純粋な数学計算）

## 備考

- Plane.intersectLine()で平面との交点計算に使用
- distanceSqToLine3はChrister Ericsonの"Real-Time Collision Detection"を基にしている
- Rayクラス（半直線）とは異なり、有限の長さを持つ
- clampToLineパラメータで直線上の最近点と線分上の最近点を切り替え可能

---

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

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

### 推奨読解順序

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

Line3クラスはstart（Vector3）とend（Vector3）で線分を表現する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Vector3.js | `src/math/Vector3.js` | Line3が依存する3Dベクトルクラス |
| 1-2 | Line3.js | `src/math/Line3.js` | クラスのプロパティ定義（start, end） |

**読解のコツ**: Line3はRayと異なり、有限の長さを持つ。パラメータt（0-1）で線分上の点を表現する。

#### Step 2: 基本操作を理解する

Line3クラスの基本的な操作メソッドを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Line3.js | `src/math/Line3.js` | set, copy, getCenter, delta, distance |

**主要処理フロー**:
1. **24-40行目**: コンストラクタでstart/endを初期化
2. **49-56行目**: set() - 始点と終点を設定
3. **79-82行目**: getCenter() - (start + end) * 0.5
4. **91-94行目**: delta() - end - start
5. **113-117行目**: distance() - sqrt(distanceSq())

#### Step 3: 最近点計算を理解する

点との最近点計算ロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Line3.js | `src/math/Line3.js` | closestPointToPointParameter, closestPointToPoint |

**主要処理フロー**:
- **139-157行目**: closestPointToPointParameter() - パラメータtを計算
  - **141-145行目**: ベクトル計算
  - **149-153行目**: clampToLineでのクランプ処理
- **167-173行目**: closestPointToPoint() - パラメータからat()で座標を取得

#### Step 4: 線分同士の距離計算を理解する

2線分間の最短距離計算アルゴリズムを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Line3.js | `src/math/Line3.js` | distanceSqToLine3()の詳細 |

**主要処理フロー**:
- **183-294行目**: distanceSqToLine3() - Ericsonアルゴリズム
  - **185-189行目**: "Real-Time Collision Detection"への参照
  - **199-220行目**: 線分が点に縮退している場合の処理
  - **244-281行目**: 一般的な非縮退ケースの処理
  - **287-292行目**: 最終的な距離計算

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

```
Line3
    │
    ├─ getCenter(target)
    │      └─ target = (start + end) * 0.5
    │
    ├─ delta(target)
    │      └─ target = end - start
    │
    ├─ at(t, target)
    │      ├─ delta(target)
    │      └─ target = start + delta * t
    │
    ├─ closestPointToPointParameter(point, clampToLine)
    │      ├─ _startP = point - start
    │      ├─ _startEnd = end - start
    │      ├─ t = dot(startEnd, startP) / dot(startEnd, startEnd)
    │      └─ if (clampToLine) clamp(t, 0, 1)
    │
    ├─ closestPointToPoint(point, clampToLine, target)
    │      ├─ t = closestPointToPointParameter()
    │      └─ at(t, target)
    │
    └─ distanceSqToLine3(line, c1, c2)
           ├─ 方向ベクトル d1, d2 の計算
           ├─ ドット積 a, e, f, c, b の計算
           ├─ 縮退ケースの処理（点になっている場合）
           ├─ s, t のパラメータ計算
           └─ 最近点 c1, c2 と距離の返却
```

### データフロー図

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

Vector3 ───────────▶ closestPointToPoint() ───▶ Vector3
(点)                  (最近点パラメータ計算)     (線分上の最近点)
                      ↓
                      clampToLine で線分/直線 切替

Line3 ─────────────▶ distanceSqToLine3() ─────▶ number
(他の線分)            (Ericsonアルゴリズム)      (距離の二乗)
                      ↓
                      c1, c2 で最近点も取得可能

Matrix4 ───────────▶ applyMatrix4() ───────────▶ Line3
(変換行列)            (両端点を変換)             (変換後)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Line3.js | `src/math/Line3.js` | ソース | 線分クラス本体 |
| Vector3.js | `src/math/Vector3.js` | ソース | 3Dベクトルクラス（依存） |
| MathUtils.js | `src/math/MathUtils.js` | ソース | clamp関数（最近点計算で使用） |
| Plane.js | `src/math/Plane.js` | ソース | 平面クラス（intersectLineで使用） |
| Matrix4.js | `src/math/Matrix4.js` | ソース | 変換行列（applyMatrix4で使用） |
