# 機能設計書 37-LatheGeometry

## 概要

本ドキュメントはThree.jsにおける回転体ジオメトリ（LatheGeometry）クラスの機能設計を記述する。LatheGeometryはBufferGeometryを継承し、2Dプロファイル曲線をY軸周りに回転させて3D形状を生成するジオメトリクラスである。

### 本機能の処理概要

LatheGeometryは3Dグラフィックスにおいて回転対称形状（ろくろで作った形状のようなもの）のメッシュを生成するためのジオメトリクラスである。2D空間上の点の配列（プロファイル）を定義し、それをY軸周りに回転させることで花瓶、ワイングラス、壺などの回転対称な3D形状を作成できる。

**業務上の目的・背景**：3Dグラフィックスにおいて回転対称な形状は非常に一般的である。花瓶、カップ、ボトル、チェスの駒、テーブルの脚など、多くのオブジェクトが回転対称形状を持つ。LatheGeometryは任意の2Dプロファイルから3D形状を生成できるため、デザイナーがカスタム形状を容易に作成できる。

**機能の利用シーン**：3Dエディタでのカスタム形状作成、ゲーム開発における回転対称オブジェクトの生成、プロダクトデザインの可視化、建築・インテリアデザインの装飾要素作成。

**主要な処理内容**：
1. 2D点配列（Vector2またはVector3）を受け取る
2. 各点のX座標を半径として使用（X座標が0より大きい必要あり）
3. Y軸周りに指定した角度だけ回転させて頂点を生成
4. 隣接する点間の法線を平均化して滑らかな法線を計算
5. UV座標を回転角度と点の位置に基づいて生成

**関連システム・外部連携**：レンダラー（WebGLRenderer、WebGPURenderer）と連携してメッシュを描画する。マテリアルと組み合わせてMeshオブジェクトを構成する。

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

## 関連画面

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

## 機能種別

計算処理 / ジオメトリ生成

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| points | Array<Vector2\|Vector3> | No | 2D空間上の点の配列（デフォルト: 3点の三角形） | X座標 > 0 |
| segments | number | No | 周方向の分割数（デフォルト: 12） | Math.floorで整数化 |
| phiStart | number | No | 開始角度（ラジアン、デフォルト: 0） | なし |
| phiLength | number | No | 回転角度（ラジアン、デフォルト: Math.PI * 2） | clamp(0, 2*PI) |

### 入力データソース

コンストラクタ引数として直接指定される。点配列は通常ユーザーが定義するか、曲線オブジェクトから取得する。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| position | Float32BufferAttribute | 頂点の3D位置座標 |
| normal | Float32BufferAttribute | 頂点の法線ベクトル |
| uv | Float32BufferAttribute | テクスチャマッピング用UV座標 |
| index | Uint16/Uint32BufferAttribute | 三角形面のインデックス |

### 出力先

BufferGeometry属性として保持され、Meshオブジェクトを通じてGPUに送信される。

## 処理フロー

### 処理シーケンス

```
1. コンストラクタ呼び出し
   └─ 引数（points, segments, phiStart, phiLength）を受け取る
2. 初期法線を計算
   └─ 点列の各点で隣接点との差分から法線を計算
3. 頂点生成ループ（二重ループ）
   └─ segments × points.length の頂点を生成
4. 各頂点の座標をY軸周りに回転
5. 法線も同様に回転
6. インデックス生成
7. BufferGeometry属性を設定
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[コンストラクタ引数を受け取る]
    B --> C[phiLengthをクランプ: 0〜2PI]
    C --> D[初期法線計算ループ]
    D --> E[segmentsループ]
    E --> F[phi = phiStart + i/segments × phiLength]
    F --> G[pointsループ]
    G --> H[頂点座標: x×sin, y, x×cos]
    H --> I[法線を回転]
    I --> J[UV座標計算]
    J --> K{全points完了?}
    K -->|No| G
    K -->|Yes| L{全segments完了?}
    L -->|No| E
    L -->|Yes| M[インデックス生成]
    M --> N[BufferGeometry属性設定]
    N --> O[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-37-001 | phiLength範囲 | phiLengthは0〜2PIにクランプ | 常時 |
| BR-37-002 | 点のX座標 | 各点のX座標は半径として使用（0より大きい必要あり） | 常時 |
| BR-37-003 | 法線平滑化 | 隣接点の法線を平均化して滑らかな表面を実現 | 常時 |
| BR-37-004 | UV座標 | u = i/segments, v = j/(points.length-1) | 常時 |

### 計算ロジック

回転による頂点座標変換:
- vertex.x = points[j].x * sin(phi)
- vertex.y = points[j].y
- vertex.z = points[j].x * cos(phi)

初期法線計算（最初の子午線上）:
- normal.x = dy（隣接点のy差分）
- normal.y = -dx（隣接点のx差分の符号反転）
- normal.z = 0

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | phiLength < 0 または > 2PI | 自動的にクランプ |
| - | 注意 | points[].x <= 0 | 結果が不正になる可能性 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- 頂点数は (segments+1) × points.length
- 三角形数は segments × (points.length-1) × 2
- 複雑なプロファイルはpoints数を増やして表現

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

特になし（クライアントサイドのジオメトリ生成処理）

## 備考

- 閉じた形状（phiLength = 2*PI）では最初と最後のセグメントが接続される
- 部分的な回転（phiLength < 2*PI）で扇形の回転体を生成可能
- デフォルトのpoints配列は単純な三角形プロファイル

---

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

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

### 推奨読解順序

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

入力となる点配列とBufferGeometryの属性構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Vector2.js | `src/math/Vector2.js` | 2Dベクトル（プロファイル点） |
| 1-2 | Vector3.js | `src/math/Vector3.js` | 3Dベクトル（頂点、法線） |
| 1-3 | BufferGeometry.js | `src/core/BufferGeometry.js` | 頂点属性の管理方法 |

**読解のコツ**: pointsのx座標が半径、y座標が高さとして使われる。これをY軸周りに回転させるイメージで読み解く。

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

LatheGeometryクラスのコンストラクタが処理の起点。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | LatheGeometry.js | `src/geometries/LatheGeometry.js` | コンストラクタ全体の処理フロー |

**主要処理フロー**:
1. **36行目**: コンストラクタでパラメータを受け取る
2. **56行目**: segmentsを整数化
3. **60行目**: phiLengthをクランプ（0〜2PI）
4. **83-133行目**: 初期法線計算ループ
5. **137-171行目**: 頂点生成の二重ループ
6. **175-193行目**: インデックス生成ループ

#### Step 3: 法線計算の詳細を理解する

初期法線と法線の平滑化処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | LatheGeometry.js | `src/geometries/LatheGeometry.js` | 83-133行目の法線計算 |

**主要処理フロー**:
- **87-102行目**: 最初の点の法線計算（次の点との差分）
- **104-108行目**: 最後の点の法線計算（前の法線を使用）
- **110-131行目**: 中間点の法線計算（前後の平均）

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

```
LatheGeometry.constructor()
    │
    ├─ BufferGeometry.constructor()
    │
    ├─ phiLength = clamp(phiLength, 0, 2*PI)
    │
    ├─ 初期法線計算ループ（j: 0→points.length-1）
    │      ├─ 最初の点: 次の点との差分
    │      ├─ 最後の点: 前の法線を使用
    │      └─ 中間点: 前後の平均
    │
    ├─ segmentsループ（i: 0→segments）
    │      │
    │      ├─ phi = phiStart + i/segments × phiLength
    │      │
    │      └─ pointsループ（j: 0→points.length-1）
    │             ├─ vertex.x = points[j].x × sin(phi)
    │             ├─ vertex.y = points[j].y
    │             ├─ vertex.z = points[j].x × cos(phi)
    │             ├─ normal回転
    │             └─ uv計算
    │
    ├─ インデックス生成ループ
    │
    └─ setAttribute()
           ├─ position
           ├─ uv
           └─ normal
```

### データフロー図

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

points配列 ───▶ LatheGeometry ───▶ BufferGeometry属性
(Vector2[])        │                 (position,
                   │                  normal,
segments,          ▼                  uv,
phiStart,       法線計算              index)
phiLength          │
                   ▼
               Y軸周り回転
                   │
                   ▼
               頂点生成
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| LatheGeometry.js | `src/geometries/LatheGeometry.js` | ソース | 回転体ジオメトリクラス定義 |
| BufferGeometry.js | `src/core/BufferGeometry.js` | ソース | 基底クラス、属性管理 |
| BufferAttribute.js | `src/core/BufferAttribute.js` | ソース | Float32BufferAttribute定義 |
| Vector3.js | `src/math/Vector3.js` | ソース | 3Dベクトル計算 |
| Vector2.js | `src/math/Vector2.js` | ソース | 2Dベクトル（プロファイル点） |
| MathUtils.js | `src/math/MathUtils.js` | ソース | clamp関数 |
