# 4次元立体を描画したい
## 実装方法
- WebGL
- Web で見れてうれしいね
## 多胞体 (polychoron) の構成
- とりあえず超立方体 Tesseract を描画したい
- Tesseract は 8 つの立方体で構成される
- 立方体は 5 つの四面体で構成される
## 描画手順
### 実装する関数
#### 定義
- $\mathbb{N}$: `unsigned int`
- $\mathbb{R}$: `float`
#### 入力
- $(x, y) \in \mathbb{N}^2$: 画面上のピクセル座標
- $\mathbf{c} \in \mathbb{R}^4$: カメラの位置
- $\mathbf{a} \in \mathbb{R}^4$: カメラの向き
- $\mathcal{P}$: 描画対象の多胞体 (胞の集合)
- $\mathcal{C} \in \mathcal{P}$: 胞
- $\mathcal{T} \in \mathcal{C}$: 四面体
- $\mathbf{v}_i$: 4D頂点座標 × 4
- $e_i$: 辺の描画の是非 × 6
##### パラメータ
- $p$: 画面の POV 角 (横)
- $(w, h)$: 画面の解像度
- $f$: 霧の濃さ (遠くのものをどれだけ薄く(明るく)するか)
#### 出力
<!-- - $(r, g, b)$: 画面上の対応するピクセルの色 -->
- $v$: 画面上の対応するピクセルの明るさ
### 処理手順
1. $(x, y), \mathbf{a}$ → カメラから出る ray の単位向きベクトル $\hat{\mathbf{r}}$
- $\hat{x} := \frac{2x}{w}-1$
- $\hat{y} := \frac{2y}{h}-1$
- $\delta=\tan\frac{\pi-p}{2}$
- $\theta=\text{atan2}(\hat x, \delta)$
- $\phi=\text{atan2}(\hat y, \delta)$
- $\hat{\mathbf{r}} = \text{angle2vec}\left(\text{vec2angle}(\mathbf{a}) + \left(\begin{matrix}0\\\theta\\\phi\end{matrix}\right)\right)$
2. $\mathbf{c}, \hat{\mathbf{r}}$, 各 $\mathcal{T}_i \in \mathcal{C} \in \mathcal{P}$ → 多胞体までの距離 $d$ (交わらない場合は無限)
- $\mathcal{T}$ のうち 1 つの頂点 $\mathbf{o}$ を選択し、そこを起点とする3つのベクトルを $\mathbf{v}_1, \mathbf{v}_2, \mathbf{v}_3$ とする。
- $D := \left|\mathbf{v}_1, \mathbf{v}_2, \mathbf{v}_3, -\hat{\mathbf{r}}\right| \in \det(\mathbb{R}^{4 \times 4})=\mathbb{R}$
- $k_1 := \frac{1}{D}\left|\mathbf{c}-\mathbf{o}, \mathbf{v}_2, \mathbf{v}_3, -\hat{\mathbf{r}}\right|$
- $k_2 := \frac{1}{D}\left|\mathbf{v}_1, \mathbf{c}-\mathbf{o}, \mathbf{v}_3, -\hat{\mathbf{r}}\right|$
- $k_3 := \frac{1}{D}\left|\mathbf{v}_1, \mathbf{v}_2, \mathbf{c}-\mathbf{o}, -\hat{\mathbf{r}}\right|$
- $t := \frac{1}{D} \left|\mathbf{v}_1, \mathbf{v}_2, \mathbf{v}_3, \mathbf{c}-\mathbf{o}\right|$
- $d_i := \begin{cases}t&\text{if } 0 \le k_1, k_2, k_3, k_1+k_2+k_3 \le 1\\\infty&\text{otherwise}\end{cases}$
- $d = \min(d_i)$
3. $d$ -> $v$
- $v=\exp(-(df)^2)$
## 4D のピッチ・ヨー~1~・ヨー~2~

直交系座標 $\mathbf{v}=[w, x, y, z]$
極座標系座標 $\mathbf{\Theta}=(\psi, \theta, \phi)$
- ピッチ $\psi$: 重力軸 (Z軸) との原点からのなす角
- ヨー~1~ $\theta$: XY 平面への射影の X 軸とのなす角
- ヨー~2~ $\phi$: XW 平面への射影の X 軸とのなす角
### $\text{vec2angle}$
4次元ベクトルを3軸の4次元角度系に変換 ($\mathbf{v}\mapsto\mathbf{\Theta}$)
- $\psi$
- $=\frac{\pi}{2}-\arccos(\frac{\mathbf{v}}{\|\mathbf{v}\|}\cdot[0,0,0,1])$
- $=\frac{\pi}{2}-\arccos \frac{z}{\|\mathbf{v}\|}$
- $\theta$
- $=\text{atan2}(y, x)$
- ただし、$\text{atan2}(\mathbb{R}^2)=(-\pi, \pi]$
- $\phi$
- $=\text{atan2}(w, x)$
- $\mathbf{\Theta}=(\psi, \theta, \phi)$
### $\text{angle2vec}$
3軸の4次元角度系を4次元単位ベクトルに変換 ($\mathbf{\Theta}\mapsto\frac{\mathbf{v}}{\|\mathbf{v}\|}$)
- $z$ (方程式)
- $=\|\mathbf{v}\|\cos(\frac{\pi}{2}-\psi)$
- $=\|\mathbf{v}\|\sin\psi$
- $x$ (方程式)
- $s_x=\begin{cases}1&\text{if }|\theta|\le\frac{\pi}{2}\\-1&\text{otherwise}\end{cases}$
- $x=\sqrt{\|\mathbf{v}\|^2-w^2-y^2-z^2}$
- $y$ (方程式)
- $=x\tan\theta$
- $w$ (方程式)
- $=x\tan\phi$
- $\hat x=\frac{x}{\|\mathbf{v}\|}$
- $x=\sqrt{\|\mathbf{v}\|^2-(x\tan\phi)^2-(x\tan\theta)^2-z^2}$
- $x=\sqrt{\|\mathbf{v}\|^2-(x\tan\phi)^2-(x\tan\theta)^2-\|\mathbf{v}\|^2\sin^2\psi}$
- $\frac{x}{\|\mathbf{v}\|}=\sqrt{1-\left(\frac{x}{\|\mathbf{v}\|}\tan\phi\right)^2-\left(\frac{x}{\|\mathbf{v}\|}\tan\theta\right)^2-\sin^2\psi}$
- $x':=\frac{x}{\|\mathbf{v}\|}$
- $x'=\sqrt{1-\left(x'\tan\phi\right)^2-\left(x'\tan\theta\right)^2-\sin^2\psi}$
- $x'^2=1-\left(x'\tan\phi\right)^2-\left(x'\tan\theta\right)^2-\sin^2\psi$
- $x'^2(1+\tan^2\phi+\tan^2\theta)=1-\sin^2\psi$
- $x'^2(1+\tan^2\phi+\tan^2\theta)=\cos^2\psi$
- $x'^2=\frac{\cos^2\psi}{1+\tan^2\phi+\tan^2\theta}$
- $x'=\sqrt{\frac{\cos^2\psi}{1+\tan^2\phi+\tan^2\theta}}$
- $\hat x:=s_xx'$
- $\hat x=s_x\sqrt{\frac{\cos^2\psi}{1+\tan^2\phi+\tan^2\theta}}$
- $\hat y=\frac{y}{\|\mathbf{v}\|}$
- $\hat x\tan\theta$
- $\hat w=\frac{w}{\|\mathbf{v}\|}$
- $\hat x\tan\phi$
- $\hat z$
- $\sin\psi$
## 2 直線間の距離
- https://obelisk2.hatenablog.com/entry/20101228/1293521247
- https://obelisk2.hatenablog.com/entry/20161126/1480168655
---
## 修正前
### 実装する関数
#### util 関数
- $\text{vec2angle}$: 4次元ベクトルを3軸の4次元角度系に変換
- 実装済み
- $\text{angle2vec}$: 3軸の4次元角度系を4次元単位ベクトルに変換
- 実装済み
### 処理手順
1. $(x, y), \mathbf{a}$ → カメラから出る ray の単位向きベクトル $\hat{\mathbf{r}}$
- $p_w := p$
- $p_h := \frac{p h}{w}$
- $\hat{x} := \frac{2x}{w}-1$
- $\hat{y} := \frac{2y}{h}-1$
- $\theta := \frac{\pi}{2} - p_h \hat{y}$
- $\phi := p_w \hat{x}$
- $\hat{\mathbf{r}} = \text{angle2vec}\left(\text{vec2angle}(\mathbf{a}) + \left(\begin{matrix}0\\\theta\\\phi\end{matrix}\right)\right)$