# 機能設計書 33-TorusKnotGeometry

## 概要

本ドキュメントはThree.jsにおけるトーラスノット（結び目）ジオメトリ（TorusKnotGeometry）クラスの機能設計を記述する。TorusKnotGeometryはBufferGeometryを継承し、数学的なトーラスノット形状を生成するジオメトリクラスである。

### 本機能の処理概要

TorusKnotGeometryは3Dグラフィックスにおいてトーラスノット（トーラス結び目）形状のメッシュを生成するためのジオメトリクラスである。pとqの互いに素な整数のペアによって定義される特定の結び目形状を作成する。これは数学的に美しい曲線であり、装飾的なオブジェクトやアート作品に適している。

**業務上の目的・背景**：3Dグラフィックスにおいて、視覚的にインパクトのある複雑な形状を手軽に生成する需要がある。トーラスノットは数学的に定義された優美な曲線であり、ロゴデザイン、アート作品、科学的な可視化、ローディングアニメーションなど多様な用途で使用される。TorusKnotGeometryはこの複雑な形状を簡単なパラメータで生成可能にする。

**機能の利用シーン**：3Dエディタでのデコレーションオブジェクト作成、ゲーム開発における装飾的要素の追加、数学的な曲線の可視化、アート作品やロゴのデザイン、WebGLデモやショーケースでの使用。

**主要な処理内容**：
1. pとqのパラメータに基づいてトーラスノット曲線を計算
2. 曲線上の各点でFrenet-Serretフレーム（接線・法線・従法線）を計算
3. チューブ状の押し出しで3Dメッシュを生成
4. 頂点位置、法線、UV座標を自動生成

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

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 12 | Menubar - Add | 補助機能 | TorusKnotメッシュの追加 |

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| radius | number | No | トーラスノットの半径（デフォルト: 1） | なし |
| tube | number | No | チューブの半径（デフォルト: 0.4） | なし |
| tubularSegments | number | No | 曲線方向の分割数（デフォルト: 64） | Math.floorで整数化 |
| radialSegments | number | No | チューブ断面方向の分割数（デフォルト: 8） | Math.floorで整数化 |
| p | number | No | 回転対称軸周りの巻き数（デフォルト: 2） | なし |
| q | number | No | トーラス内部での巻き数（デフォルト: 3） | なし |

### 入力データソース

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

## 出力仕様

### 出力データ

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

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. コンストラクタ呼び出し
   └─ 引数（radius, tube, tubularSegments, p, q等）を受け取る
2. パラメータを整数化
   └─ tubularSegments, radialSegmentsをMath.floorで処理
3. 曲線上の点を計算
   └─ calculatePositionOnCurve関数でP1, P2を計算
4. Frenet-Serretフレーム計算
   └─ 接線T、法線N、従法線Bを計算
5. チューブ頂点生成
   └─ 曲線周りに円形断面を押し出し
6. BufferGeometry属性を設定
   └─ setIndex, setAttributeで属性を登録
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[コンストラクタ引数を受け取る]
    B --> C[segments値を整数化]
    C --> D[tubularSegmentsループ]
    D --> E[calculatePositionOnCurve: P1, P2計算]
    E --> F[Frenet-Serretフレーム計算: T, N, B]
    F --> G[radialSegmentsループ]
    G --> H[チューブ断面頂点計算]
    H --> I[法線計算]
    I --> J{全セグメント完了?}
    J -->|No| G
    J -->|Yes| K{全曲線セグメント完了?}
    K -->|No| D
    K -->|Yes| L[インデックス生成]
    L --> M[BufferGeometry属性設定]
    M --> N[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-33-001 | トーラスノット曲線 | x = radius*(2+cs)*0.5*cu, y = radius*(2+cs)*su*0.5, z = radius*sin(qu/p)*0.5 | 常時 |
| BR-33-002 | Frenet-Serretフレーム | T = P2-P1, N = B×T（正規化） | 常時 |
| BR-33-003 | pとqの関係 | pとqが互いに素な場合は結び目、そうでない場合はリンク | 常時 |

### 計算ロジック

トーラスノット曲線のパラメトリック方程式:
```javascript
const cu = Math.cos(u);
const su = Math.sin(u);
const quOverP = q / p * u;
const cs = Math.cos(quOverP);

position.x = radius * (2 + cs) * 0.5 * cu;
position.y = radius * (2 + cs) * su * 0.5;
position.z = radius * Math.sin(quOverP) * 0.5;
```

ここで u = 曲線パラメータ（0 から 2πp まで）

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | 特別なエラー処理なし | パラメータは暗黙的に処理される |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- 頂点数は (tubularSegments+1) × (radialSegments+1)
- 三角形数は tubularSegments × radialSegments × 2
- デフォルト設定（64×8）で約585頂点、約1,024三角形

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

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

## 備考

- p=2, q=3（デフォルト）で三葉結び目（trefoil knot）を生成
- pとqを変更することで様々な結び目形状を生成可能
- p=2, q=5や p=3, q=7など素数の組み合わせが美しい形状を生成

---

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

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

### 推奨読解順序

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

BufferGeometryの属性構造とベクトル計算を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | BufferGeometry.js | `src/core/BufferGeometry.js` | 頂点属性の管理方法 |
| 1-2 | Vector3.js | `src/math/Vector3.js` | 3Dベクトル演算（subVectors, addVectors, crossVectors, normalize） |

**読解のコツ**: Frenet-Serretフレーム（T, N, B）の計算にはベクトルの外積・内積が使用される。これらの数学的背景を理解すると処理の意味がわかりやすい。

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

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

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

**主要処理フロー**:
1. **32行目**: コンストラクタでパラメータを受け取る
2. **54-55行目**: tubularSegments, radialSegmentsを整数化
3. **78-133行目**: 二重ループで頂点・法線・UV生成
4. **87-88行目**: calculatePositionOnCurveでP1, P2を計算
5. **92-100行目**: Frenet-Serretフレーム計算
6. **137-155行目**: インデックス生成ループ

#### Step 3: 曲線計算の詳細を理解する

calculatePositionOnCurve関数の内部処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TorusKnotGeometry.js | `src/geometries/TorusKnotGeometry.js` | 166-177行目のcalculatePositionOnCurve関数 |

**主要処理フロー**:
- **168-169行目**: cu = cos(u), su = sin(u)
- **170行目**: quOverP = q/p * u
- **171行目**: cs = cos(quOverP)
- **173-175行目**: トーラスノット曲線上の点を計算

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

```
TorusKnotGeometry.constructor()
    │
    ├─ BufferGeometry.constructor()
    │
    ├─ tubularSegmentsループ（i: 0→tubularSegments）
    │      │
    │      ├─ calculatePositionOnCurve(u, p, q, radius, P1)
    │      ├─ calculatePositionOnCurve(u+0.01, p, q, radius, P2)
    │      │
    │      ├─ Frenet-Serretフレーム計算
    │      │      ├─ T = P2 - P1
    │      │      ├─ N = (P2 + P1)
    │      │      └─ B = T × N, N = B × T
    │      │
    │      └─ radialSegmentsループ（j: 0→radialSegments）
    │             ├─ vertex = P1 + cx*N + cy*B
    │             ├─ normal = (vertex - P1).normalize()
    │             └─ uv計算
    │
    ├─ インデックス生成ループ
    │
    └─ setAttribute()
           ├─ position
           ├─ normal
           └─ uv
```

### データフロー図

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

パラメータ ───▶ TorusKnotGeometry ───▶ BufferGeometry属性
(radius,           │                 (position,
 tube,             │                  normal,
 p, q,             ▼                  uv,
 segments)    曲線計算              index)
               (calculatePositionOnCurve)
                   │
                   ▼
              フレーム計算
               (T, N, B)
                   │
                   ▼
              チューブ押し出し
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| TorusKnotGeometry.js | `src/geometries/TorusKnotGeometry.js` | ソース | トーラスノットジオメトリクラス定義 |
| BufferGeometry.js | `src/core/BufferGeometry.js` | ソース | 基底クラス、属性管理 |
| BufferAttribute.js | `src/core/BufferAttribute.js` | ソース | Float32BufferAttribute定義 |
| Vector3.js | `src/math/Vector3.js` | ソース | 3Dベクトル計算 |
