# 機能設計書 140-Cylindrical

## 概要

本ドキュメントは、Three.jsの数学ライブラリにおける円筒座標を表現するCylindricalクラスの機能設計書である。

### 本機能の処理概要

Cylindricalクラスは、3D空間における点を[円筒座標系](https://en.wikipedia.org/wiki/Cylindrical_coordinate_system)で表現するためのクラスである。X-Z平面における原点からの距離（radius）、Z軸正方向から反時計回りに測った角度（theta）、X-Z平面からの高さ（y）の3つのパラメータで位置を定義する。円筒形の配置や回転軸を中心とした操作に適している。

**業務上の目的・背景**：3Dグラフィックスにおいて、円筒座標は螺旋状の配置、円柱上への点の配置、回転対称なオブジェクトの位置計算など、デカルト座標よりも自然に表現できる操作に使用される。特に、カルーセルUI、タワー型の配置、パイプラインの可視化などで有用である。

**機能の利用シーン**：
- カルーセル・回転メニューの配置
- 螺旋状のオブジェクト配置
- 円柱表面上への点の配置
- 回転軸を中心としたカメラワーク
- 円形のパーティクルエフェクト
- パイプラインや円筒形構造物の可視化

**主要な処理内容**：
1. 円筒座標の生成と初期化（radius, theta, y）
2. Vector3（デカルト座標）からの変換
3. デカルト座標への逆変換（Vector3.setFromCylindrical）
4. 座標値の直接設定とコピー

**関連システム・外部連携**：Vector3と連携。Spherical（球面座標）と概念的に類似。

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

## 関連画面

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

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 円筒座標系を使用するカスタム配置で使用 |

## 機能種別

計算処理 / 座標変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| radius | number | No | X-Z平面における原点からの距離 | デフォルト: 1 |
| theta | number | No | Z軸正方向から反時計回りの角度（ラジアン） | デフォルト: 0 |
| y | number | No | X-Z平面からの高さ | デフォルト: 0 |

### 入力データソース

コンストラクタ引数、メソッド呼び出し、またはVector3からの変換

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| radius | number | X-Z平面における原点からの距離 |
| theta | number | Z軸正方向から反時計回りの角度（ラジアン） |
| y | number | X-Z平面からの高さ |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. 円筒座標の初期化
   └─ radius=1, theta=0, y=0で初期化
2. 座標の設定
   ├─ set: 直接設定
   ├─ setFromVector3: デカルト座標から変換
   └─ setFromCartesianCoords: x,y,zから変換
3. 利用側での変換
   └─ Vector3.setFromCylindrical: デカルト座標へ変換
```

### フローチャート

```mermaid
flowchart TD
    A[Cylindricalインスタンス生成] --> B{設定方法}
    B -->|set| C[radius/theta/yを直接設定]
    B -->|setFromVector3| D[Vector3から変換]
    B -->|setFromCartesianCoords| E[x,y,zから変換]
    D --> F[setFromCartesianCoordsを呼び出し]
    E --> G[radiusを計算: sqrt/x*x+z*z/]
    F --> G
    G --> H[thetaを計算: atan2/x,z/]
    H --> I[yをそのまま使用]
    C --> J[円筒座標確定]
    I --> J
    J --> K{デカルト座標へ変換?}
    K -->|Yes| L[Vector3.setFromCylindrical]
    K -->|No| M[そのまま使用]
    L --> N[x=radius*sin/theta/]
    N --> O[z=radius*cos/theta/]
    O --> P[y=y]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | Y-up座標系 | Y軸が上方向として扱われる | 全操作 |
| BR-002 | 角度の基準 | thetaはZ軸正方向から反時計回りに測定 | setFromCartesianCoords |
| BR-003 | X-Z平面 | radiusはX-Z平面上での距離（yは無関係） | setFromCartesianCoords |

### 計算ロジック

**デカルト座標から円筒座標への変換**:
```javascript
radius = sqrt(x*x + z*z)  // X-Z平面での距離
theta = atan2(x, z)        // Z軸からの角度
y = y                      // 高さはそのまま
```

**円筒座標からデカルト座標への変換**（Vector3.setFromCylindricalCoords）:
```javascript
x = radius * sin(theta)
y = y
z = radius * cos(theta)
```

**球面座標（Spherical）との違い**:
- Cylindrical: (radius, theta, y) - radiusはX-Z平面での距離、yは高さ
- Spherical: (radius, phi, theta) - radiusは原点からの3D距離、phiはY軸からの角度

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

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

## エラー処理

### エラーケース一覧

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

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- 全メソッドO(1)の計算量
- メモリ使用量: number x 3 = 24バイト程度

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

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

## 備考

- Sphericalとは異なり、makeSafe()のような特異点回避メソッドは不要（円筒座標には極の特異点がないため）
- theta=0はZ軸正方向、theta=PI/2はX軸正方向
- radiusが0の場合、thetaの値は任意（どの角度でも同じ点を指す）
- 螺旋を表現する場合、thetaとyを連動させて増加させる

---

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

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

### 推奨読解順序

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

Cylindricalクラスはradius, theta, yの3つの数値で円筒座標を表現する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Cylindrical.js | `src/math/Cylindrical.js` | クラスのプロパティ定義（radius, theta, y） |
| 1-2 | Vector3.js | `src/math/Vector3.js` | setFromCylindricalでの逆変換を確認 |

**読解のコツ**: Three.jsはY-up座標系を採用。radiusはX-Z平面（水平面）での距離、yは高さ（垂直方向）を表す。Spherical（球面座標）との違いを意識すると理解しやすい。

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

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

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

**主要処理フロー**:
1. **14-40行目**: コンストラクタでradius/theta/yを初期化
2. **50-58行目**: set() - 値を直接設定
3. **66-74行目**: copy() - 他のCylindricalからコピー
4. **112-116行目**: clone() - 新しいインスタンスを作成してコピー

#### Step 3: 座標変換を理解する

デカルト座標との相互変換を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Cylindrical.js | `src/math/Cylindrical.js` | setFromVector3, setFromCartesianCoords |
| 3-2 | Vector3.js | `src/math/Vector3.js` | setFromCylindrical, setFromCylindricalCoords |

**主要処理フロー**:
- **83-87行目**: setFromVector3() - Vector3からの変換（setFromCartesianCoordsを呼び出し）
- **97-105行目**: setFromCartesianCoords() - x,y,zからの変換
  - **99行目**: radius = sqrt(x*x + z*z) - X-Z平面での距離
  - **100行目**: theta = atan2(x, z) - Z軸からの角度
  - **101行目**: y = y - 高さはそのまま

**Vector3側の逆変換**（src/math/Vector3.js）:
- **1021-1025行目**: setFromCylindrical() - Cylindricalからの変換
- **1035-1043行目**: setFromCylindricalCoords() - radius,theta,yからの変換
  - **1037行目**: x = radius * sin(theta)
  - **1038行目**: y = y
  - **1039行目**: z = radius * cos(theta)

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

```
Cylindrical
    │
    ├─ set(radius, theta, y)
    │      └─ 直接プロパティに設定
    │
    ├─ copy(other)
    │      └─ other.radius/theta/yをコピー
    │
    ├─ setFromVector3(v)
    │      └─ setFromCartesianCoords(v.x, v.y, v.z)
    │
    ├─ setFromCartesianCoords(x, y, z)
    │      ├─ radius = sqrt(x*x + z*z)
    │      ├─ theta = atan2(x, z)
    │      └─ y = y
    │
    └─ clone()
           └─ new Cylindrical().copy(this)

Vector3.setFromCylindrical(cylindrical)
    └─ setFromCylindricalCoords(radius, theta, y)
           ├─ x = radius * sin(theta)
           ├─ y = y
           └─ z = radius * cos(theta)
```

### データフロー図

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

Vector3 ───────────▶ setFromVector3() ─────────▶ Cylindrical
(デカルト座標)          setFromCartesianCoords()   {radius, theta, y}
                        ↓
                        radius = sqrt(x*x + z*z)
                        theta = atan2(x, z)
                        y = y

Cylindrical ───────▶ Vector3.setFromCylindrical() ▶ Vector3
                     (逆変換)                       (デカルト座標)
                        ↓
                        x = radius * sin(theta)
                        y = y
                        z = radius * cos(theta)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Cylindrical.js | `src/math/Cylindrical.js` | ソース | 円筒座標クラス本体 |
| Vector3.js | `src/math/Vector3.js` | ソース | setFromCylindrical/setFromCylindricalCoordsで使用 |
| Spherical.js | `src/math/Spherical.js` | ソース | 類似の球面座標クラス |
