# 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~ ![](https://i.imgur.com/2WVaXFN.png) 直交系座標 $\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)$