# 機能設計書: Vector4（4次元ベクトル）

## 1. 機能概要

### 1.1 機能の目的
Vector4は、4次元空間における点や方向を表現するためのクラスである。同次座標（homogeneous coordinates）、クォータニオンデータ、シェーダーへのユニフォーム値、クリッピング平面など、4成分を必要とするデータに使用される。

### 1.2 主な機能
- 4次元ベクトルの基本演算（加算、減算、乗算、除算）
- ベクトルの正規化、長さ計算
- 内積計算
- 線形補間（lerp）
- 4x4行列変換の適用
- イテレータによる成分アクセス

### 1.3 関連する画面/コンポーネント
- 同次座標変換
- シェーダーユニフォーム
- クリッピング平面の定義
- カラーデータ（RGBA）

## 2. 機能仕様

### 2.1 データ構造

```javascript
class Vector4 {
    x: number;  // X成分
    y: number;  // Y成分
    z: number;  // Z成分
    w: number;  // W成分
    isVector4: boolean;  // 型判定フラグ
}
```

### 2.2 プロパティ詳細

| プロパティ名 | 型 | 説明 | デフォルト値 |
|-------------|-----|------|-------------|
| x | number | X成分 | 0 |
| y | number | Y成分 | 0 |
| z | number | Z成分 | 0 |
| w | number | W成分 | 1 |
| isVector4 | boolean | 型判定フラグ（読み取り専用） | true |
| width | number | zの別名アクセサ | - |
| height | number | wの別名アクセサ | - |

### 2.3 メソッド詳細（主要なもの）

#### 2.3.1 基本操作
| メソッド | 説明 |
|---------|------|
| set(x, y, z, w) | 成分を設定 |
| setScalar(scalar) | 全成分を同じ値に設定 |
| setX/Y/Z/W(value) | 個別成分を設定 |
| clone() | 複製を作成 |
| copy(v) | 他のベクトルをコピー |

#### 2.3.2 算術演算
| メソッド | 説明 |
|---------|------|
| add(v) | ベクトル加算 |
| addScalar(s) | スカラー加算 |
| sub(v) | ベクトル減算 |
| multiply(v) | 成分ごとの乗算 |
| multiplyScalar(s) | スカラー乗算 |
| divide(v) | 成分ごとの除算 |
| divideScalar(s) | スカラー除算 |

#### 2.3.3 長さ・正規化
| メソッド | 説明 |
|---------|------|
| length() | ベクトルの長さ |
| lengthSq() | 長さの2乗 |
| manhattanLength() | マンハッタン距離 |
| normalize() | 単位ベクトルに正規化 |
| setLength(l) | 指定長さに設定 |

#### 2.3.4 幾何学演算
| メソッド | 説明 |
|---------|------|
| dot(v) | 内積 |
| lerp(v, alpha) | 線形補間 |
| lerpVectors(v1, v2, alpha) | 2ベクトル間の線形補間 |

#### 2.3.5 変換
| メソッド | 説明 |
|---------|------|
| applyMatrix4(m) | 4x4行列を適用 |
| setFromMatrixPosition(m) | 行列から位置を抽出 |
| setAxisAngleFromQuaternion(q) | クォータニオンから軸角度を設定 |
| setAxisAngleFromRotationMatrix(m) | 回転行列から軸角度を設定 |

#### 2.3.6 比較・制限
| メソッド | 説明 |
|---------|------|
| min(v) | 各成分の最小値 |
| max(v) | 各成分の最大値 |
| clamp(min, max) | 範囲内に制限 |
| clampScalar(minVal, maxVal) | スカラー範囲内に制限 |
| floor() / ceil() / round() | 各成分を丸め |
| equals(v) | 等値比較 |

### 2.4 ビジネスルール
- ベクトル演算は元のベクトルを変更する（ミュータブル）
- w成分のデフォルト値は1（同次座標として使用する場合の慣例）
- 長さ0のベクトルを正規化するとゼロベクトルになる

### 2.5 同次座標としての使用
```javascript
// 3Dポイント（w=1）
const point = new Vector4(x, y, z, 1);

// 3D方向ベクトル（w=0）
const direction = new Vector4(dx, dy, dz, 0);

// 行列変換後、w除算で3D座標に変換
point.applyMatrix4(matrix);
const result = new Vector3(
    point.x / point.w,
    point.y / point.w,
    point.z / point.w
);
```

## 3. 処理フロー

### 3.1 4x4行列変換フロー
```
[applyMatrix4(m)]
        |
        v
[現在の成分を保存]
x, y, z, w = this.x, this.y, this.z, this.w
        |
        v
[行列要素を取得]
e = m.elements
        |
        v
[変換計算]
this.x = e[0]*x + e[4]*y + e[8]*z + e[12]*w
this.y = e[1]*x + e[5]*y + e[9]*z + e[13]*w
this.z = e[2]*x + e[6]*y + e[10]*z + e[14]*w
this.w = e[3]*x + e[7]*y + e[11]*z + e[15]*w
        |
        v
[自身を返却]
```

### 3.2 軸角度抽出フロー
```
[setAxisAngleFromQuaternion(q)]
        |
        v
[クォータニオンを正規化]
        |
        v
[w成分から角度計算]
this.w = 2 * acos(q.w)
        |
        v
[sinθ/2の計算]
s = sqrt(1 - q.w * q.w)
        |
        v
[s が小さい場合]
    |       |
  Yes      No
    |       |
    v       v
[任意の軸] [軸を計算]
this.x = 1  this.x = q.x / s
this.y = 0  this.y = q.y / s
this.z = 0  this.z = q.z / s
```

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

### 4.1 推奨読解順序
1. **Vector4.js** - クラス定義とプロパティ
2. コンストラクタとset()メソッド
3. 基本演算メソッド（add, sub, multiply, divide）
4. 長さと正規化（length, normalize）
5. 行列変換（applyMatrix4）
6. 軸角度変換（setAxisAngleFromQuaternion/RotationMatrix）

### 4.2 重要な処理の詳細

#### コンストラクタ（29-39行目）
```javascript
constructor( x = 0, y = 0, z = 0, w = 1 ) {
    Vector4.prototype.isVector4 = true;
    this.x = x;
    this.y = y;
    this.z = z;
    this.w = w;
}
```
**30行目**: 型判定フラグをプロトタイプに設定
**31-34行目**: 成分の初期化（wのデフォルトは1）

#### applyMatrix4()（266-282行目）
```javascript
applyMatrix4( m ) {
    const x = this.x, y = this.y, z = this.z, w = this.w;
    const e = m.elements;

    this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w;
    this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w;
    this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w;
    this.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w;

    return this;
}
```
4x4行列による完全な同次座標変換

#### setAxisAngleFromQuaternion()（302-326行目）
```javascript
setAxisAngleFromQuaternion( q ) {
    // q is assumed to be normalized
    this.w = 2 * Math.acos( q.w );
    const s = Math.sqrt( 1 - q.w * q.w );

    if ( s < 0.0001 ) {
        this.x = 1;
        this.y = 0;
        this.z = 0;
    } else {
        this.x = q.x / s;
        this.y = q.y / s;
        this.z = q.z / s;
    }

    return this;
}
```
クォータニオンを軸角度表現に変換（x,y,zが軸、wが角度）

### 4.3 プログラム呼び出し階層図
```
Vector4
├── 基本操作
│   ├── set() / setScalar() / setX/Y/Z/W()
│   ├── setComponent() / getComponent()
│   └── clone() / copy()
├── 算術演算
│   ├── add() / addScalar() / addVectors()
│   ├── sub() / subScalar() / subVectors()
│   ├── multiply() / multiplyScalar()
│   └── divide() / divideScalar()
├── 長さ・正規化
│   ├── length() / lengthSq() / manhattanLength()
│   ├── normalize() / setLength()
│   └── negate()
├── 比較・制限
│   ├── min() / max() / clamp() / clampScalar()
│   ├── floor() / ceil() / round() / roundToZero()
│   └── equals()
├── 幾何学演算
│   ├── dot()
│   └── lerp() / lerpVectors()
├── 変換
│   ├── applyMatrix4()
│   ├── setAxisAngleFromQuaternion()
│   ├── setAxisAngleFromRotationMatrix()
│   └── setFromMatrixPosition()
├── 補間
│   └── random()
└── 配列変換
    ├── fromArray() / toArray()
    └── fromBufferAttribute()
```

### 4.4 データフロー図
```
[入力値 (x, y, z, w)]
      |
      v
[Vector4インスタンス]
      |
      +---> [Matrix4変換] ---> [変換後Vector4]
      |
      +---> [正規化] ---> [単位Vector4]
      |
      +---> [軸角度抽出] ---> [軸(x,y,z) + 角度(w)]
      |
      +---> [配列変換] ---> [number[4]]
```

### 4.5 関連ファイル一覧
| ファイルパス | 種別 | 役割 |
|-------------|------|------|
| src/math/Vector4.js | メイン | Vector4クラスの実装 |
| src/math/Matrix4.js | 関連 | 4x4行列変換 |
| src/math/Quaternion.js | 関連 | クォータニオンからの変換 |
| src/core/BufferAttribute.js | 関連 | 頂点データアクセス |
| src/math/MathUtils.js | 関連 | 数学ユーティリティ |

## 5. 使用例

### 5.1 基本的な使用例
```javascript
// ベクトルの作成
const v1 = new THREE.Vector4(1, 2, 3, 1);
const v2 = new THREE.Vector4(4, 5, 6, 1);

// 加算
v1.add(v2);  // v1 = (5, 7, 9, 2)

// 長さの計算
const length = v1.length();  // √(25 + 49 + 81 + 4)
```

### 5.2 同次座標変換
```javascript
// 3Dポイントを同次座標で表現
const point = new THREE.Vector4(10, 5, 3, 1);

// 透視投影行列を適用
const projMatrix = camera.projectionMatrix;
point.applyMatrix4(projMatrix);

// 正規化デバイス座標（NDC）に変換
point.divideScalar(point.w);
```

### 5.3 クリッピング平面
```javascript
// 平面方程式 ax + by + cz + d = 0
// (a, b, c)は法線、dは原点からの距離
const plane = new THREE.Vector4(0, 1, 0, -5);
// y = 5 の平面
```

### 5.4 軸角度表現
```javascript
const quaternion = new THREE.Quaternion();
quaternion.setFromAxisAngle(
    new THREE.Vector3(0, 1, 0),
    Math.PI / 2
);

// 軸角度に変換
const axisAngle = new THREE.Vector4();
axisAngle.setAxisAngleFromQuaternion(quaternion);
// x,y,z = 軸 (0, 1, 0), w = 角度 (Math.PI / 2)
```

### 5.5 シェーダーユニフォーム
```javascript
// 4成分のデータをシェーダーに渡す
material.uniforms.customData = {
    value: new THREE.Vector4(1.0, 0.5, 0.0, 1.0)
};
```

## 6. 備考

### 6.1 パフォーマンス考慮事項
- length()よりlengthSq()が高速（平方根計算なし）
- 同次座標からの変換（w除算）は必要な場合のみ実行
- オブジェクト再利用でGC負荷軽減

### 6.2 Vector3との違い
| 項目 | Vector3 | Vector4 |
|------|---------|---------|
| 成分数 | 3 (x, y, z) | 4 (x, y, z, w) |
| デフォルトw | - | 1 |
| 主な用途 | 位置、方向 | 同次座標、平面 |
| 外積 | あり | なし |

### 6.3 注意事項
- w成分のデフォルトが1であることに注意
- applyMatrix4()は同次座標変換を行う（w除算は自動では行われない）
- setAxisAngleFromQuaternion()はクォータニオンが正規化されていることを前提とする
