# 機能設計書 114-SliderAngle

## 概要

本ドキュメントは、Dear ImGuiライブラリにおける角度スライダー機能「SliderAngle」の設計を詳細に記述したものである。

### 本機能の処理概要

SliderAngleは、ラジアン単位で格納されている角度値を度数法（degrees）で表示・編集できるスライダーウィジェットを作成する機能である。内部的には値をラジアンから度に変換して表示し、編集後は度からラジアンに戻して格納する。

**業務上の目的・背景**：プログラミングにおいて角度は通常ラジアンで管理されるが、人間にとっては度数法の方が直感的に理解しやすい。SliderAngleは、内部データはラジアンのまま保持しつつ、ユーザーインターフェースでは度数法で表示・編集できるようにすることで、開発者とエンドユーザー双方の利便性を向上させる。ゲームオブジェクトの回転角度、カメラのFOV、ライトの照射角度など、角度パラメータの調整に特に有用である。

**機能の利用シーン**：
- オブジェクトの回転角度（pitch/yaw/roll）を調整するとき
- カメラの視野角（FOV）を設定するとき
- ライトのスポットライト角度を調整するとき
- 物理シミュレーションの角度パラメータを設定するとき

**主要な処理内容**：
1. ラジアン値を度数に変換（v_rad * 360 / (2 * PI)）
2. SliderFloatで度数法スライダーを表示
3. 値が変更された場合、度数をラジアンに戻して格納（v_deg * (2 * PI) / 360）

**関連システム・外部連携**：本機能は単体で動作し、外部システムとの直接的な連携はない。内部的にSliderFloatを呼び出す。

**権限による制御**：ImGuiItemFlags_ReadOnlyフラグまたはImGuiSliderFlags_ReadOnlyフラグにより読み取り専用モードを設定可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 23 | Widgets | 主機能 | スライダーウィジェットのデモ表示 |

## 機能種別

インタラクティブウィジェット / ユーザー入力処理 / 単位変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| label | const char* | Yes | ウィジェットのラベル（ID生成にも使用） | NULL不可 |
| v_rad | float* | Yes | 編集対象の角度値（ラジアン単位）へのポインタ | NULL不可 |
| v_degrees_min | float | No | スライダーの最小値（度数法、デフォルト: -360.0f） | 任意 |
| v_degrees_max | float | No | スライダーの最大値（度数法、デフォルト: +360.0f） | 任意 |
| format | const char* | No | 表示フォーマット文字列（デフォルト: "%.0f deg"） | printf形式 |
| flags | ImGuiSliderFlags | No | 動作制御フラグ（デフォルト: 0） | 有効なフラグの組み合わせ |

### 入力データソース

ユーザーからのマウス操作（クリック・ドラッグ）およびキーボード入力。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | bool | 値が変更された場合true |
| *v_rad | float | 更新された角度値（ラジアン単位） |

### 出力先

呼び出し元への戻り値、およびv_radが指すメモリ領域への値の書き込み。

## 処理フロー

### 処理シーケンス

```
1. デフォルトフォーマットの設定
   └─ formatがNULLの場合、"%.0f deg"を使用
2. ラジアンから度数への変換
   └─ v_deg = (*v_rad) * 360.0f / (2 * IM_PI)
3. SliderFloat呼び出し
   └─ SliderFloat(label, &v_deg, v_degrees_min, v_degrees_max, format, flags)
4. 値変更時の逆変換
   └─ value_changedがtrueの場合: *v_rad = v_deg * (2 * IM_PI) / 360.0f
5. 結果を返却
```

### フローチャート

```mermaid
flowchart TD
    A[SliderAngle呼び出し] --> B{format == NULL?}
    B -->|Yes| C[format = "%.0f deg"]
    B -->|No| D[ラジアン→度数変換]
    C --> D
    D --> E["v_deg = v_rad * 360 / 2PI"]
    E --> F[SliderFloat呼び出し]
    F --> G{value_changed?}
    G -->|Yes| H["v_rad = v_deg * 2PI / 360"]
    G -->|No| I[return value_changed]
    H --> I
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-114-1 | 単位変換 | 内部値はラジアン、表示値は度数 | 常時 |
| BR-114-2 | デフォルト範囲 | -360度〜+360度をデフォルト範囲とする | v_degrees_min/max未指定時 |
| BR-114-3 | 表示形式 | デフォルトで"deg"サフィックス付きの整数表示 | format未指定時 |
| BR-114-4 | 精度維持 | 変換による精度損失は浮動小数点の精度範囲内 | 常時 |

### 計算ロジック

ラジアン ⇔ 度数の変換：

```
度数 = ラジアン * 360.0 / (2 * PI)
     = ラジアン * 180.0 / PI

ラジアン = 度数 * (2 * PI) / 360.0
         = 度数 * PI / 180.0
```

実装では `360.0f / (2 * IM_PI)` および `(2 * IM_PI) / 360.0f` を使用。

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

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | アサーション | 無効なImGuiSliderFlagsが渡された場合 | 正しいフラグ値を使用する |

### リトライ仕様

本機能はユーザー入力ウィジェットであり、リトライは適用されない。

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

本機能はトランザクション処理を行わない。

## パフォーマンス要件

フレームごとに呼び出されるため、軽量な処理が求められる。変換処理は単純な乗除算のみであり、オーバーヘッドは無視できる程度。

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

- format文字列の検証は呼び出し側の責任
- 値の範囲外入力はSliderFloatの動作に従う

## 備考

- IM_PIは`imgui.h`で定義されている円周率定数
- 360度を超える角度の表現が必要な場合も、デフォルト範囲をカスタマイズすることで対応可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui.h | `imgui.h` | SliderAngle関数宣言（700行目） |
| 1-2 | imgui.h | `imgui.h` | IM_PI定数の定義 |

**読解のコツ**: デフォルトパラメータ値に注目。v_degrees_min = -360.0f、v_degrees_max = +360.0fとなっており、一周分の角度がデフォルトでカバーされている。

#### Step 2: 実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | imgui_widgets.cpp | `imgui_widgets.cpp` | SliderAngle関数（3443-3452行目） |

**主要処理フロー**:
1. **3445-3446行目**: デフォルトフォーマット設定
2. **3447行目**: ラジアン→度数変換
3. **3448行目**: SliderFloat呼び出し
4. **3449-3450行目**: 値変更時の度数→ラジアン逆変換
5. **3451行目**: 結果返却

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

```
SliderAngle (imgui_widgets.cpp:3443)
    │
    ├─ ラジアン→度数変換
    │
    └─ SliderFloat (imgui_widgets.cpp:3423)
           │
           └─ SliderScalar (imgui_widgets.cpp:3295)
                  │
                  └─ SliderBehavior (imgui_widgets.cpp:3257)
                         └─ SliderBehaviorT<float>
```

### データフロー図

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

*v_rad (ラジアン)
       │
       ▼
v_deg = v_rad * 360 / 2PI ──▶ SliderFloat ──▶ v_deg (度数で編集)
                                   │
                                   ▼
                              value_changed?
                                   │
                                   ▼ (Yes)
*v_rad ◀── v_deg * 2PI / 360 ◀─── v_deg (編集後)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui.h | `imgui.h` | ヘッダー | SliderAngle関数宣言、IM_PI定義 |
| imgui_widgets.cpp | `imgui_widgets.cpp` | ソース | SliderAngle実装 |
