# 機能設計書 30-CylinderGeometry

## 概要

本ドキュメントは、Three.jsにおけるCylinderGeometry（円柱ジオメトリ）機能の詳細設計を記述する。CylinderGeometryは円柱（円錐台を含む）の3Dジオメトリを生成するクラスである。

### 本機能の処理概要

CylinderGeometryは、指定された上面半径、下面半径、高さ、セグメント数に基づいて円柱のジオメトリ（頂点、法線、UV座標、インデックス）を生成するクラスである。上面と下面の半径を異なる値に設定することで円錐台（截頭円錐）を、どちらかを0にすることで円錐を生成できる。

**業務上の目的・背景**：円柱は3Dグラフィックスにおいて基本的な形状の一つであり、柱、パイプ、ボトル、タンク、木の幹など多くのオブジェクトの基礎として使用される。CylinderGeometryを使用することで、プログラム的に円柱や円錐のメッシュを生成でき、パラメータを調整することで様々なバリエーションを作成できる。

**機能の利用シーン**：
- 建築物の柱や支柱の表現
- 機械部品やパイプの表現
- 缶やボトルなどの容器
- 木の幹や植物の茎
- 物理シミュレーションのコリジョン形状
- UIの円柱状要素

**主要な処理内容**：
1. 側面（トルソ）の頂点・法線・UVの生成
2. 上面キャップの生成（openEnded=false時）
3. 下面キャップの生成（openEnded=false時）
4. 三角形メッシュ用のインデックス生成
5. マルチマテリアル用のグループ設定

**関連システム・外部連携**：BufferGeometry、BufferAttribute、Mesh、マテリアルシステムと連携して動作する。

**権限による制御**：特になし（ライブラリ機能として権限制御は行わない）。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 5 | Sidebar - Geometry | 補助機能 | 円柱パラメータの編集 |
| 12 | Menubar - Add | 補助機能 | Cylinderメッシュの追加 |
| 35 | Geometry Browser | 主機能 | 円柱ジオメトリのプレビュー |

## 機能種別

データ生成 / ジオメトリ生成

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| radiusTop | number | No | 上面の半径 | デフォルト: 1 |
| radiusBottom | number | No | 下面の半径 | デフォルト: 1 |
| height | number | No | 高さ | デフォルト: 1 |
| radialSegments | number | No | 円周方向のセグメント数 | デフォルト: 32 |
| heightSegments | number | No | 高さ方向のセグメント数 | デフォルト: 1 |
| openEnded | boolean | No | 上下の面を開けるかどうか | デフォルト: false |
| thetaStart | number | No | 開始角度（ラジアン） | デフォルト: 0 |
| thetaLength | number | No | 角度範囲 | デフォルト: Math.PI * 2 |

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| type | string | 'CylinderGeometry' |
| parameters | Object | コンストラクタパラメータのコピー |
| index | BufferAttribute | 三角形インデックス |
| attributes.position | Float32BufferAttribute | 頂点座標（3成分） |
| attributes.normal | Float32BufferAttribute | 法線ベクトル（3成分） |
| attributes.uv | Float32BufferAttribute | UV座標（2成分） |
| groups | Array | マルチマテリアル用グループ（側面:0、上面:1、下面:2） |

### 出力先

- Meshオブジェクトのgeometryプロパティ
- JSON形式でのシリアライズ出力

## 処理フロー

### 処理シーケンス

```
1. コンストラクタ実行
   └─ super()でBufferGeometryを初期化
   └─ type = 'CylinderGeometry' を設定
   └─ parametersオブジェクトを保存
   └─ セグメント数を整数化

2. 側面（トルソ）の生成
   └─ generateTorso()関数
   └─ 高さ方向でループ
   └─ 円周方向でループ
      └─ 頂点座標を計算
      └─ 法線を計算（スロープ考慮）
      └─ UV座標を計算
   └─ インデックス生成
   └─ グループ追加（materialIndex: 0）

3. キャップの生成（openEnded=false時）
   └─ generateCap(true): 上面キャップ
   └─ generateCap(false): 下面キャップ
   └─ 各キャップにグループ追加（上面:1、下面:2）

4. バッファ属性の設定
```

### フローチャート

```mermaid
flowchart TD
    A[CylinderGeometry生成] --> B[パラメータ保存]
    B --> C[セグメント数整数化]
    C --> D[generateTorso実行]
    D --> E{openEnded?}
    E -->|No| F{radiusTop > 0?}
    F -->|Yes| G[generateCap上面]
    F -->|No| H{radiusBottom > 0?}
    G --> H
    H -->|Yes| I[generateCap下面]
    H -->|No| J[バッファ属性設定]
    I --> J
    E -->|Yes| J
    J --> K[完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 原点中心 | ジオメトリは原点を中心に生成される | 常時 |
| BR-02 | Y軸配置 | 円柱の軸はY軸に沿う | 常時 |
| BR-03 | スロープ法線 | 側面の法線はスロープ（テーパー角度）を考慮 | radiusTop != radiusBottom時 |
| BR-04 | キャップスキップ | 半径が0の場合、そのキャップは生成しない | radiusTop/Bottom == 0時 |
| BR-05 | マテリアルグループ | 側面=0、上面=1、下面=2 | マルチマテリアル使用時 |

### 計算ロジック

側面の法線計算（スロープ考慮）:

```javascript
// スロープの計算
slope = (radiusBottom - radiusTop) / height

// 各頂点の法線
normal.set(
  sin(theta),      // X成分（円周方向）
  slope,           // Y成分（スロープ）
  cos(theta)       // Z成分（円周方向）
).normalize()
```

頂点座標の計算:

```javascript
// 現在の高さでの半径
radius = v * (radiusBottom - radiusTop) + radiusTop

// 頂点座標
x = radius * sin(theta)
y = -v * height + halfHeight
z = radius * cos(theta)
```

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

該当なし（クライアントサイドのみの処理）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | 明示的なエラー処理なし | 半径0での円錐生成は正常動作 |

### リトライ仕様

リトライ処理は不要

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

該当なし（クライアントサイドのみの処理）

## パフォーマンス要件

- 側面頂点数 = (radialSegs + 1) * (heightSegs + 1)
- キャップ頂点数 = radialSegs * 2 + 2（各キャップ）
- デフォルト設定で約66頂点

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

特になし（ブラウザのセキュリティモデルに依存）

## 備考

- 円錐を生成するにはradiusTopまたはradiusBottomを0に設定
- thetaLengthを調整することで部分的な円柱（扇形）を生成可能
- ConeGeometryはCylinderGeometryを継承して実装
- fromJSON()静的メソッドでJSONからインスタンス化可能

---

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

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

### 推奨読解順序

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

CylinderGeometryはBufferGeometryを継承した円柱生成クラス。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | CylinderGeometry.js | `src/geometries/CylinderGeometry.js` | クラスの全体構造（334行） |
| 1-2 | BufferGeometry.js | `src/core/BufferGeometry.js` | 親クラスの構造 |
| 1-3 | Vector3.js | `src/math/Vector3.js` | 頂点・法線計算に使用 |
| 1-4 | Vector2.js | `src/math/Vector2.js` | キャップUV計算に使用 |

**読解のコツ**: generateTorso()とgenerateCap()の2つの内部関数を理解することが重要。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | CylinderGeometry.js | `src/geometries/CylinderGeometry.js` | 34-94行目 |

**主要処理フロー**:
1. **36行目**: super()でBufferGeometryを初期化
2. **38行目**: type = 'CylinderGeometry' を設定
3. **47-56行目**: parametersオブジェクトを保存
4. **60-61行目**: セグメント数をfloor()で整数化
5. **79行目**: generateTorso()を呼び出し
6. **81-86行目**: openEnded=falseの場合、キャップを生成
7. **90-93行目**: バッファ属性を設定

#### Step 3: generateTorso()を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | CylinderGeometry.js | `src/geometries/CylinderGeometry.js` | 95-195行目 |

**主要処理フロー**:
- **103行目**: スロープ計算 `slope = (radiusBottom - radiusTop) / height`
- **107-151行目**: 頂点生成ループ
  - **115行目**: 現在の高さでの半径を計算
  - **128-131行目**: 頂点座標を計算
  - **135行目**: 法線を設定（スロープ考慮）
- **156-185行目**: インデックス生成ループ
- **189行目**: addGroup()でマテリアルインデックス設定

#### Step 4: generateCap()を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | CylinderGeometry.js | `src/geometries/CylinderGeometry.js` | 197-303行目 |

**主要処理フロー**:
- **207行目**: 上面/下面に応じた半径と符号を設定
- **214-232行目**: 中心頂点の生成（セグメント数分）
- **239-268行目**: 周囲の頂点生成
- **272-293行目**: インデックス生成
- **297行目**: addGroup()でマテリアルインデックス設定（上面:1、下面:2）

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

```
CylinderGeometry
    |
    +-- extends BufferGeometry
    |
    +-- constructor(radiusTop, radiusBottom, height, radialSegs, heightSegs, openEnded, thetaStart, thetaLength)
    |       |
    |       +-- super()
    |       +-- generateTorso()
    |       |       +-- スロープ計算
    |       |       +-- 頂点生成ループ
    |       |       +-- インデックス生成
    |       |       +-- addGroup(0)
    |       |
    |       +-- generateCap(true)  [if !openEnded && radiusTop > 0]
    |       |       +-- 中心頂点生成
    |       |       +-- 周囲頂点生成
    |       |       +-- インデックス生成
    |       |       +-- addGroup(1)
    |       |
    |       +-- generateCap(false) [if !openEnded && radiusBottom > 0]
    |       |       +-- addGroup(2)
    |       |
    |       +-- setIndex()
    |       +-- setAttribute()
    |
    +-- copy(source)
    |
    +-- static fromJSON(data)
```

### データフロー図

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

radiusTop, radiusBottom, -> CylinderGeometry構築 ────> CylinderGeometryインスタンス
height, radialSegs, etc.         |                           |
                                 v                           v
                          generateTorso()           position: Float32BufferAttribute
                                 |                   normal: Float32BufferAttribute
                                 v                   uv: Float32BufferAttribute
                          スロープ考慮法線計算        index: BufferAttribute
                                 |                   groups: [{0: 側面}, {1: 上面}, {2: 下面}]
                                 v
                          generateCap() x 2
                                 |
                                 v
                          Mesh.geometryとして使用 ───> レンダリング
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| CylinderGeometry.js | `src/geometries/CylinderGeometry.js` | ソース | CylinderGeometryクラスの実装 |
| ConeGeometry.js | `src/geometries/ConeGeometry.js` | ソース | CylinderGeometryを継承した円錐 |
| BufferGeometry.js | `src/core/BufferGeometry.js` | ソース | 親クラス |
| BufferAttribute.js | `src/core/BufferAttribute.js` | ソース | 頂点属性の格納 |
| Vector3.js | `src/math/Vector3.js` | ソース | 頂点・法線計算に使用 |
| Vector2.js | `src/math/Vector2.js` | ソース | キャップUV計算に使用 |
| Mesh.js | `src/objects/Mesh.js` | ソース | ジオメトリを使用するオブジェクト |
