# 機能設計書 35-RingGeometry

## 概要

本ドキュメントはThree.jsにおけるリング形状ジオメトリ（RingGeometry）クラスの機能設計を記述する。RingGeometryはBufferGeometryを継承し、2次元のリング（ドーナツ型平面）形状を生成するジオメトリクラスである。

### 本機能の処理概要

RingGeometryは3Dグラフィックスにおいてリング形状（内側と外側の半径を持つ平面的なドーナツ型）のメッシュを生成するためのジオメトリクラスである。内径と外径を指定することで、様々なサイズと太さのリング形状を作成できる。

**業務上の目的・背景**：3Dグラフィックスでは中央が空いた円形のオブジェクトが頻繁に必要となる。ワッシャー、CD/DVDディスク、時計の文字盤、ターゲットマーカー、ハローエフェクトなど多くのオブジェクトがリング形状を基本としている。RingGeometryはこれらの形状を効率的に生成する。

**機能の利用シーン**：3Dエディタでの平面オブジェクト作成、ゲーム開発におけるUI要素やマーカーの作成、データ可視化におけるドーナツグラフの基盤、デカールやエフェクトの表示。

**主要な処理内容**：
1. 内側の半径から外側の半径まで放射状に頂点を配置
2. 周方向（thetaSegments）と径方向（phiSegments）で分割
3. 開始角度と中心角を指定して部分的なリングも生成可能
4. すべての法線はZ軸正方向（0, 0, 1）
5. UV座標は外側の半径に基づいて計算

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

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

## 関連画面

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

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| innerRadius | number | No | 内側の半径（デフォルト: 0.5） | なし |
| outerRadius | number | No | 外側の半径（デフォルト: 1） | なし |
| thetaSegments | number | No | 周方向の分割数（デフォルト: 32） | Math.max(3, thetaSegments) |
| phiSegments | number | No | 径方向の分割数（デフォルト: 1） | Math.max(1, phiSegments) |
| thetaStart | number | No | 開始角度（ラジアン、デフォルト: 0） | なし |
| thetaLength | number | No | 中心角（ラジアン、デフォルト: Math.PI * 2） | なし |

### 入力データソース

コンストラクタ引数として直接指定される。

## 出力仕様

### 出力データ

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

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. コンストラクタ呼び出し
   └─ 引数（innerRadius, outerRadius, thetaSegments等）を受け取る
2. segments値を検証
   └─ thetaSegments >= 3, phiSegments >= 1を保証
3. 頂点生成ループ（二重ループ）
   └─ 内側から外側へ、周方向に頂点を配置
4. インデックス生成
   └─ 四角形を2つの三角形に分割
5. BufferGeometry属性を設定
   └─ setIndex, setAttributeで属性を登録
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[コンストラクタ引数を受け取る]
    B --> C[segments検証: theta>=3, phi>=1]
    C --> D[phiSegmentsループ: 内側→外側]
    D --> E[thetaSegmentsループ: 周方向]
    E --> F[頂点座標: radius*cos/sin]
    F --> G[法線: 0,0,1]
    G --> H[UV座標計算]
    H --> I{全周完了?}
    I -->|No| E
    I -->|Yes| J[radius += radiusStep]
    J --> K{全径方向完了?}
    K -->|No| D
    K -->|Yes| L[インデックス生成]
    L --> M[BufferGeometry属性設定]
    M --> N[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-35-001 | 最小セグメント数 | thetaSegments >= 3, phiSegments >= 1 を保証 | 常時 |
| BR-35-002 | 半径増分 | radiusStep = (outerRadius - innerRadius) / phiSegments | 常時 |
| BR-35-003 | 法線方向 | すべての頂点の法線は(0, 0, 1) | 常時 |
| BR-35-004 | UV座標 | outerRadiusを基準に正規化 | 常時 |

### 計算ロジック

リング頂点のパラメトリック方程式:
- x = radius * cos(thetaStart + i/thetaSegments * thetaLength)
- y = radius * sin(thetaStart + i/thetaSegments * thetaLength)
- z = 0

radius = innerRadius + j * (outerRadius - innerRadius) / phiSegments

UV座標:
- u = (x / outerRadius + 1) / 2
- v = (y / outerRadius + 1) / 2

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | thetaSegments < 3 | 自動的に3に補正 |
| - | - | phiSegments < 1 | 自動的に1に補正 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- 頂点数は (phiSegments+1) × (thetaSegments+1)
- 三角形数は phiSegments × thetaSegments × 2
- デフォルト設定で66頂点、64三角形

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

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

## 備考

- innerRadius=0の場合は円形（CircleGeometryと同等）になるが、中心点がない
- phiSegments > 1で複数の同心円層を持つリングを生成
- thetaStartとthetaLengthで扇形リングを生成可能

---

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

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

### 推奨読解順序

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

BufferGeometryの属性構造を理解することが重要。

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

**読解のコツ**: RingGeometryはCircleGeometryと似ているが、内側と外側の2つの半径を持ち、中心点がない構造。

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

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

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

**主要処理フロー**:
1. **31行目**: コンストラクタでパラメータを受け取る
2. **53-54行目**: thetaSegments >= 3, phiSegments >= 1を保証
3. **65-66行目**: 初期半径とradiusStepを計算
4. **72-104行目**: 二重ループで頂点・法線・UV生成
5. **108-128行目**: インデックス生成ループ
6. **132-135行目**: BufferGeometry属性設定

#### Step 3: 頂点計算の詳細を理解する

頂点座標とUV座標の計算ロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | RingGeometry.js | `src/geometries/RingGeometry.js` | 72-104行目の頂点生成ループ |

**主要処理フロー**:
- **78行目**: segment = thetaStart + i/thetaSegments * thetaLength
- **82-83行目**: vertex.x = radius * cos(segment), vertex.y = radius * sin(segment)
- **93-94行目**: UV座標計算: (vertex.x/outerRadius + 1) / 2
- **102行目**: radius += radiusStep（次の層へ）

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

```
RingGeometry.constructor()
    │
    ├─ BufferGeometry.constructor()
    │
    ├─ 初期化
    │      ├─ radius = innerRadius
    │      └─ radiusStep = (outerRadius - innerRadius) / phiSegments
    │
    ├─ phiSegmentsループ（j: 0→phiSegments）
    │      │
    │      ├─ thetaSegmentsループ（i: 0→thetaSegments）
    │      │      ├─ vertex.x = radius * cos(segment)
    │      │      ├─ vertex.y = radius * sin(segment)
    │      │      ├─ normals.push(0, 0, 1)
    │      │      └─ uvs計算
    │      │
    │      └─ radius += radiusStep
    │
    ├─ インデックス生成ループ
    │      └─ 四角形→2三角形変換
    │
    └─ setAttribute()
           ├─ position
           ├─ normal
           └─ uv
```

### データフロー図

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

パラメータ ───▶ RingGeometry ───▶ BufferGeometry属性
(innerRadius,       │                 (position,
 outerRadius,       │                  normal,
 segments,          ▼                  uv,
 thetaStart等)  頂点計算              index)
               (内側→外側へ)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RingGeometry.js | `src/geometries/RingGeometry.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ベクトル（UV座標） |
