# 機能設計書 165-Path

## 概要

本ドキュメントは、Three.jsライブラリにおけるPath機能の設計仕様を記述する。Pathは、2D空間でのパス表現を提供するクラスであり、2D Canvas APIに類似したメソッドでパスを構築する機能を持つ。

### 本機能の処理概要

Pathクラスは、CurvePathを継承し、2Dパスの作成に特化した機能を提供する。moveTo、lineTo、quadraticCurveTo、bezierCurveTo、arc、ellipseなど、Canvas 2D APIと同様のメソッドでパスを構築できる。構築されたパスは、ShapeGeometryやExtrudeGeometryの入力として使用される。

**業務上の目的・背景**：2Dグラフィックスやベクターグラフィックスにおいて、パスは基本的な描画プリミティブである。SVGパスの解析、フォントグリフの表現、2Dシェイプの輪郭定義など、様々な用途でパス機能が必要とされる。PathクラスはCanvas 2D APIに親しんだ開発者が直感的に使用できるインターフェースを提供する。

**機能の利用シーン**：
- SVGパスデータの解析と表現
- フォントグリフのアウトライン作成
- 2Dシェイプの輪郭定義
- BufferGeometryへの変換用ポイント生成
- Shapeの外形定義

**主要な処理内容**：
1. moveTo() - 現在位置を移動
2. lineTo() - 現在位置から直線を追加
3. quadraticCurveTo() - 2次ベジェ曲線を追加
4. bezierCurveTo() - 3次ベジェ曲線を追加
5. splineThru() - スプライン曲線を追加
6. arc() / absarc() - 円弧を追加
7. ellipse() / absellipse() - 楕円弧を追加
8. setFromPoints() - 点配列からパスを生成

**関連システム・外部連携**：Shape、ShapeGeometry、ExtrudeGeometry、フォントローダー、SVGローダーと連携。

**権限による制御**：特になし。すべてのユーザーが利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 直接的な画面関連なし（基盤クラス） |

## 機能種別

計算処理 / データ構造

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| points | Array<Vector2> | No | 初期化用の点配列 | Vector2の配列 |
| x, y | number | Yes | 座標値 | 有効な数値 |
| aCPx, aCPy | number | Yes | 制御点座標（2次ベジェ） | 有効な数値 |
| aCP1x, aCP1y, aCP2x, aCP2y | number | Yes | 制御点座標（3次ベジェ） | 有効な数値 |
| aRadius | number | No | 円弧の半径 | 正の数値 |
| xRadius, yRadius | number | No | 楕円の半径 | 正の数値 |
| aStartAngle, aEndAngle | number | No | 開始・終了角度（ラジアン） | 数値 |
| aClockwise | boolean | No | 時計回りかどうか | - |
| aRotation | number | No | 楕円の回転角度 | 数値 |

### 入力データソース

各メソッドの引数として渡される座標値やパラメータ。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Path | Path | 構築されたパスオブジェクト |
| currentPoint | Vector2 | 現在の描画位置 |
| curves | Array<Curve> | パスを構成する曲線の配列 |

### 出力先

メモリ上に保持され、getPoints()等で点配列として取得可能。

## 処理フロー

### 処理シーケンス

```
1. Pathインスタンス生成
   └─ pointsが指定されていればsetFromPoints()を呼び出し
2. moveTo(x, y)
   └─ currentPointを設定
3. lineTo(x, y)
   └─ LineCurveを生成してcurvesに追加
   └─ currentPointを更新
4. quadraticCurveTo / bezierCurveTo
   └─ 対応するベジェ曲線を生成
   └─ currentPointを更新
5. arc / absarc / ellipse / absellipse
   └─ EllipseCurveを生成
   └─ 必要に応じてLineCurveで接続
   └─ currentPointを更新
```

### フローチャート

```mermaid
flowchart TD
    A[Path生成] --> B{points指定あり?}
    B -->|Yes| C[setFromPoints実行]
    B -->|No| D[currentPoint初期化]
    C --> D
    D --> E{描画メソッド呼び出し}
    E -->|moveTo| F[currentPoint設定]
    E -->|lineTo| G[LineCurve生成]
    G --> H[curves.push]
    H --> I[currentPoint更新]
    E -->|quadraticCurveTo| J[QuadraticBezierCurve生成]
    J --> H
    E -->|bezierCurveTo| K[CubicBezierCurve生成]
    K --> H
    E -->|arc/ellipse| L[EllipseCurve生成]
    L --> M{接続必要?}
    M -->|Yes| N[LineCurve追加]
    M -->|No| O[曲線追加]
    N --> O
    O --> I
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 現在位置管理 | currentPointで描画位置を追跡 | 常時 |
| BR-002 | 相対arc | arc()はcurrentPointからの相対位置 | arc() |
| BR-003 | 絶対arc | absarc()は絶対座標 | absarc() |
| BR-004 | 曲線接続 | 楕円の開始点がcurrentPointと異なる場合、LineCurveで接続 | absellipse() |

### 計算ロジック

**arc計算**: `absarc(aX + currentPoint.x, aY + currentPoint.y, aRadius, aStartAngle, aEndAngle, aClockwise)`として相対位置を絶対位置に変換。

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

該当なし（クライアントサイドのみで動作）

## エラー処理

### エラーケース一覧

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

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- 曲線の追加はO(1)で実行
- getPoints()は曲線数に比例した計算時間

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

特になし

## 備考

- Canvas 2D APIに類似したインターフェースを提供
- Shapeクラスの基底クラスとして使用される

---

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

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

### 推奨読解順序

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

PathはCurvePathを継承し、currentPointプロパティで現在の描画位置を管理する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Path.js | `src/extras/core/Path.js` | クラス定義とプロパティ構造（31-57行目） |

**読解のコツ**: currentPointがVector2で管理され、各描画メソッドで更新される。コンストラクタでpointsが渡された場合はsetFromPoints()が呼び出される。

#### Step 2: 基本描画メソッドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Path.js | `src/extras/core/Path.js` | setFromPoints (66-78行目) |
| 2-2 | Path.js | `src/extras/core/Path.js` | moveTo (87-93行目) |
| 2-3 | Path.js | `src/extras/core/Path.js` | lineTo (103-112行目) |

**主要処理フロー**:
1. **68行目**: 最初の点でmoveTo()を実行
2. **70-72行目**: 残りの点でlineTo()を繰り返し
3. **89行目**: currentPoint.set(x, y)で位置を設定
4. **105行目**: LineCurveをcurrentPointから新しい点へ生成
5. **108行目**: currentPointを更新

#### Step 3: ベジェ曲線メソッドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Path.js | `src/extras/core/Path.js` | quadraticCurveTo (124-138行目) |
| 3-2 | Path.js | `src/extras/core/Path.js` | bezierCurveTo (152-167行目) |
| 3-3 | Path.js | `src/extras/core/Path.js` | splineThru (176-187行目) |

**主要処理フロー**:
- **126-130行目**: QuadraticBezierCurveをcurrentPointから制御点経由で終点へ生成
- **154-159行目**: CubicBezierCurveを2つの制御点経由で生成
- **178行目**: currentPointを先頭に含むスプラインを生成

#### Step 4: 円弧・楕円メソッドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Path.js | `src/extras/core/Path.js` | arc (201-211行目) |
| 4-2 | Path.js | `src/extras/core/Path.js` | absarc (224-230行目) |
| 4-3 | Path.js | `src/extras/core/Path.js` | absellipse (270-294行目) |

**主要処理フロー**:
- **203-206行目**: arc()は相対座標をabsarc()に委譲
- **226行目**: absarc()は等しいx/y半径でabsellipse()を呼び出し
- **272行目**: EllipseCurveを生成
- **274-283行目**: 曲線の開始点がcurrentPointと異なる場合、LineCurveで接続

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

```
Path extends CurvePath
    │
    ├─ setFromPoints(points)
    │      ├─ moveTo(points[0])
    │      └─ lineTo(points[i]) [繰り返し]
    │
    ├─ moveTo(x, y)
    │      └─ currentPoint.set(x, y)
    │
    ├─ lineTo(x, y)
    │      ├─ new LineCurve(currentPoint, new Vector2(x, y))
    │      └─ currentPoint.set(x, y)
    │
    ├─ quadraticCurveTo(aCPx, aCPy, aX, aY)
    │      └─ new QuadraticBezierCurve(currentPoint, cp, end)
    │
    ├─ bezierCurveTo(aCP1x, aCP1y, aCP2x, aCP2y, aX, aY)
    │      └─ new CubicBezierCurve(currentPoint, cp1, cp2, end)
    │
    ├─ splineThru(pts)
    │      └─ new SplineCurve([currentPoint, ...pts])
    │
    ├─ arc(aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise)
    │      └─ absarc(aX + x0, aY + y0, ...)
    │
    └─ absellipse(aX, aY, xRadius, yRadius, ...)
           ├─ new EllipseCurve(...)
           ├─ [Optional] lineTo(firstPoint) for connection
           └─ currentPoint = lastPoint
```

### データフロー図

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

x, y ──────────────────▶ moveTo ───────────────────────▶ currentPoint更新

currentPoint + (x,y) ──▶ lineTo ───────────────────────▶ LineCurve + curves追加

cp + end ──────────────▶ quadraticCurveTo ─────────────▶ QuadraticBezierCurve

cp1 + cp2 + end ───────▶ bezierCurveTo ────────────────▶ CubicBezierCurve

center + radius + angles ▶ absellipse ─────────────────▶ EllipseCurve
                           + [LineCurve接続]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Path.js | `src/extras/core/Path.js` | ソース | 本機能のメイン実装 |
| CurvePath.js | `src/extras/core/CurvePath.js` | ソース | 基底クラス |
| Shape.js | `src/extras/core/Shape.js` | ソース | Pathを継承したシェイプ |
| LineCurve.js | `src/extras/curves/LineCurve.js` | ソース | 直線曲線 |
| QuadraticBezierCurve.js | `src/extras/curves/QuadraticBezierCurve.js` | ソース | 2次ベジェ曲線 |
| CubicBezierCurve.js | `src/extras/curves/CubicBezierCurve.js` | ソース | 3次ベジェ曲線 |
| SplineCurve.js | `src/extras/curves/SplineCurve.js` | ソース | スプライン曲線 |
| EllipseCurve.js | `src/extras/curves/EllipseCurve.js` | ソース | 楕円曲線 |
| Vector2.js | `src/math/Vector2.js` | ソース | 2Dベクトル |
| ShapeGeometry.js | `src/geometries/ShapeGeometry.js` | ソース | シェイプジオメトリ |
| ExtrudeGeometry.js | `src/geometries/ExtrudeGeometry.js` | ソース | 押し出しジオメトリ |
