# 機能設計書 28-SphereGeometry

## 概要

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

### 本機能の処理概要

SphereGeometryは、指定された半径、水平・垂直セグメント数、および角度範囲に基づいて球体のジオメトリ（頂点、法線、UV座標、インデックス）を生成するクラスである。部分的な球体（半球、ドームなど）も生成可能。

**業務上の目的・背景**：球体は3Dグラフィックスにおいて基本的な形状の一つであり、惑星、ボール、ドーム、パーティクル、環境マッピング用のスカイボックスなど、多くの用途に使用される。SphereGeometryを使用することで、プログラム的に球体メッシュを生成でき、セグメント数や角度範囲を調整することで様々なバリエーションを作成できる。

**機能の利用シーン**：
- 惑星や天体の表現
- ボールやパーティクルの表現
- 環境マッピング用のスカイドーム
- UIの球状要素
- 物理シミュレーションのコリジョンスフィア

**主要な処理内容**：
1. 球面座標に基づく頂点座標の計算（phi、theta角度）
2. 頂点から法線ベクトルの計算（正規化）
3. テクスチャマッピング用UV座標の計算
4. 三角形メッシュ用のインデックス生成
5. 極（ポール）の特殊処理

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

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

## 関連画面

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

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| radius | number | No | 球体の半径 | デフォルト: 1 |
| widthSegments | number | No | 水平方向のセグメント数 | デフォルト: 32、最小値: 3 |
| heightSegments | number | No | 垂直方向のセグメント数 | デフォルト: 16、最小値: 2 |
| phiStart | number | No | 水平方向の開始角度（ラジアン） | デフォルト: 0 |
| phiLength | number | No | 水平方向の角度範囲 | デフォルト: Math.PI * 2 |
| thetaStart | number | No | 垂直方向の開始角度（ラジアン） | デフォルト: 0 |
| thetaLength | number | No | 垂直方向の角度範囲 | デフォルト: Math.PI |

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| type | string | 'SphereGeometry' |
| parameters | Object | コンストラクタパラメータのコピー |
| index | BufferAttribute | 三角形インデックス |
| attributes.position | Float32BufferAttribute | 頂点座標（3成分） |
| attributes.normal | Float32BufferAttribute | 法線ベクトル（3成分） |
| attributes.uv | Float32BufferAttribute | UV座標（2成分） |

### 出力先

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

## 処理フロー

### 処理シーケンス

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

2. 頂点生成ループ
   └─ 垂直方向（heightSegments + 1）でループ
   └─ 水平方向（widthSegments + 1）でループ
      └─ 球面座標から直交座標に変換
      └─ 頂点座標を追加
      └─ 法線を計算（正規化）
      └─ UV座標を計算
      └─ グリッドに頂点インデックスを保存

3. インデックス生成ループ
   └─ 極の特殊処理（上極・下極）
   └─ 通常の四角形を2つの三角形に分割

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

### フローチャート

```mermaid
flowchart TD
    A[SphereGeometry生成] --> B[パラメータ保存]
    B --> C[セグメント数の最小値チェック]
    C --> D[頂点生成ループ]
    D --> E{iy <= heightSegments?}
    E -->|Yes| F[v = iy / heightSegments計算]
    F --> G{ix <= widthSegments?}
    G -->|Yes| H[球面座標から直交座標変換]
    H --> I[頂点・法線・UV追加]
    I --> G
    G -->|No| E
    E -->|No| J[インデックス生成ループ]
    J --> K{上極?}
    K -->|Yes| L[上極用三角形生成]
    K -->|No| M{下極?}
    M -->|Yes| N[下極用三角形生成]
    M -->|No| O[通常の四角形を分割]
    L --> P[バッファ属性設定]
    N --> P
    O --> P
    P --> Q[完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 原点中心 | ジオメトリは原点を中心に生成される | 常時 |
| BR-02 | 最小セグメント | widthSegmentsは最小3、heightSegmentsは最小2 | 常時 |
| BR-03 | 極の処理 | 上極（theta=0）と下極（theta=PI）では縮退三角形を避ける | 完全な球体の場合 |
| BR-04 | UV補正 | 極での縫い目を避けるためUVオフセットを適用 | 極点の場合 |

### 計算ロジック

球面座標から直交座標への変換:

```javascript
// 角度計算
phi = phiStart + u * phiLength      // 水平角度
theta = thetaStart + v * thetaLength // 垂直角度

// 直交座標変換
x = -radius * cos(phi) * sin(theta)
y = radius * cos(theta)
z = radius * sin(phi) * sin(theta)

// 法線（球の中心から頂点への方向）
normal = vertex.clone().normalize()

// UV座標
u = ix / widthSegments
v = 1 - (iy / heightSegments)
```

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | 明示的なエラー処理なし | セグメント数はmax()で最小値を保証 |

### リトライ仕様

リトライ処理は不要

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

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

## パフォーマンス要件

- 頂点数 ≈ (widthSegs + 1) * (heightSegs + 1)
- デフォルト設定で約561頂点

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

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

## 備考

- 半球を生成するにはthetaLength = Math.PI / 2を指定
- phiLengthを調整することで部分的な球体（扇形）を生成可能
- fromJSON()静的メソッドでJSONからインスタンス化可能

---

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

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

### 推奨読解順序

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

SphereGeometryはBufferGeometryを継承したジオメトリクラス。

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

**読解のコツ**: 球面座標（phi、theta）から直交座標（x、y、z）への変換が核心部分。

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

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

**主要処理フロー**:
1. **33行目**: super()でBufferGeometryを初期化
2. **35行目**: type = 'SphereGeometry' を設定
3. **44-52行目**: parametersオブジェクトを保存
4. **54-55行目**: セグメント数の最小値チェック（max(3, ...), max(2, ...)）
5. **57行目**: thetaEnd = min(thetaStart + thetaLength, PI)
6. **74-121行目**: 頂点生成ループ
7. **125-139行目**: インデックス生成ループ

#### Step 3: 頂点生成を理解する

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

**主要処理フロー**:
- **78行目**: v = iy / heightSegments（垂直方向の割合）
- **84-90行目**: 極でのUVオフセット処理
- **100-102行目**: 球面座標から直交座標への変換
- **108行目**: 法線の計算（正規化）
- **113行目**: UV座標の計算

#### Step 4: インデックス生成を理解する

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

**主要処理フロー**:
- **129-131行目**: グリッドからabcdの4頂点を取得
- **134行目**: 上極でない場合のみ上三角形を追加
- **135行目**: 下極でない場合のみ下三角形を追加

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

```
SphereGeometry
    |
    +-- extends BufferGeometry
    |
    +-- constructor(radius, widthSegs, heightSegs, phiStart, phiLength, thetaStart, thetaLength)
    |       |
    |       +-- super()
    |       +-- Math.max() でセグメント数を制限
    |       +-- 頂点生成ループ
    |       |       +-- 球面座標から直交座標変換
    |       |       +-- normal.copy().normalize()
    |       |       +-- UV計算
    |       +-- インデックス生成ループ
    |       |       +-- 極の判定
    |       |       +-- 三角形インデックス追加
    |       +-- setIndex()
    |       +-- setAttribute('position')
    |       +-- setAttribute('normal')
    |       +-- setAttribute('uv')
    |
    +-- copy(source)
    |
    +-- static fromJSON(data)
```

### データフロー図

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

radius, widthSegs, ───> SphereGeometry構築 ────────> SphereGeometryインスタンス
heightSegs, phi*, theta*       |                           |
                               v                           v
                        球面座標変換              position: Float32BufferAttribute
                               |                   normal: Float32BufferAttribute
                               v                   uv: Float32BufferAttribute
                        x = -r*cos(phi)*sin(theta) index: BufferAttribute
                        y = r*cos(theta)
                        z = r*sin(phi)*sin(theta)
                               |
                               v
                        Mesh.geometryとして使用 ───> レンダリング
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| SphereGeometry.js | `src/geometries/SphereGeometry.js` | ソース | SphereGeometryクラスの実装 |
| BufferGeometry.js | `src/core/BufferGeometry.js` | ソース | 親クラス |
| BufferAttribute.js | `src/core/BufferAttribute.js` | ソース | 頂点属性の格納 |
| Vector3.js | `src/math/Vector3.js` | ソース | 頂点・法線計算に使用 |
| Mesh.js | `src/objects/Mesh.js` | ソース | ジオメトリを使用するオブジェクト |
