OpenGLの座標変換変換行列について

matrix.png

このページでは3Dコンピュータ・グラフィックスにおいて必要な座標変換行列の変換についての数式とコード(C++,Android)を書きます。

行列演算アプリ

web2.0calcウェブブラウザ上で行列演算できる

掛け算する順番

(1)
\begin{equation} v'=P*V*M*v \end{equation}

v=ローカル座標での頂点
V=ビュー行列(z方向への平行移動)
M=モデル行列(glLookAt)
P=プロジェクション行列
v'=変換後の頂点
上の式はOpenGL(右手座標系)の場合。
DirectX(左手座標系)の場合は逆$v'=v*M*V*P$になるので要注意。

コード

const char gSimpleVertexShader[] = 
    "attribute vec4 Position;      \n"
    "uniform mat4 Projection;      \n"
    "uniform mat4 Modelview;       \n"
    "void main() {\n"
        "   gl_Position = Projection * Modelview * Position; \n"
    "}\n";

ビューポート変換

射影変換

glFrustum(l,r,b,t,n,f)

(2)
\begin{align} \left[ \begin{array}{cc} \frac{2n}{r-l} & 0 & \frac{r+l}{r-l} & 0 \\ 0 & \frac{2n}{t-b} & \frac{t+b}{t-b} & 0 \\ 0 & 0 & \frac{-(f+n)}{f-n} & \frac{-2fn}{f-n} \\ 0 & 0 & -1 & 0\\ \end{array} \right] \end{align}

gluPerspective

(3)
\begin{align} \left[ \begin{array}{cc} \frac{\alpha}{aspect} & 0 & 0 & 0 \\ 0 & f & 0 & 0 \\ 0 & 0 & \frac{f+n}{n-f} & \frac{2fn}{n-f} \\ 0 & 0 & -1 & 0\\ \end{array} \right] \alpha=cot(fovy/2) cot=\frac{1}{tan(\frac{fovy}{2})} \end{align}

glOrtho(left,right,bottom,top,near,far)

glOrtho.PNG
l=left,r=right,b=bottom,t=top,n=nea,f=far(4)
\begin{align} \left[ \begin{array}{cc} \frac{2}{r-l} & 0 & 0 & \frac{r+l}{r-l} \\ 0 & \frac{2}{t-b} & 0 & \frac{t+b}{t-b} \\ 0 & 0 & \frac{-2}{f-n} & \frac{f+n}{f-n} \\ 0 & 0 & 0 & 1\\ \end{array} \right] \end{align}
(5)
\begin{align} l \neq r,t \neq b ,n \neq f \end{align}

でなければらない。

glOrtho2D(left,right,bottom,top)

calling glOrtho with near = -1 and far = 1 .[1]
glOrthoをnear=-1,far=1の状態で呼び出したものと同じ
よく使われるように、もしglOrtho2D(0,winwidth,winheight,0)
で呼んだら、行列はこうなる。
w=winwidth
h=winheight

(6)
\begin{align} \left[ \begin{array}{cc} \frac{2}{w} & 0 & 0 & 1 \\ 0 & -\frac{2}{h} & 0 & 1 \\ 0 & 0 & -1 & 0 \\ 0 & 0 & 0 & 1\\ \end{array} \right] \end{align}
Bibliography

モデルビュー変換

平行移動

glTranslatef(x,y,z);

(7)
\begin{align} \left[ \begin{array}{cc} 1 & 0 & 0 & x \\ 0 & 1 & 0 & y \\ 0 & 0 & 1 & z \\ 0 & 0 & 0 & 1\\ \end{array} \right] \end{align}

拡大縮小

glScalef(x,y,z)

(8)
\begin{align} \left[ \begin{array}{cc} x & 0 & 0 & 0 \\ 0 & y & 0 & 0 \\ 0 & 0 & z & 0 \\ 0 & 0 & 0 & 1\\ \end{array} \right] \end{align}

回転

glRotatef(a,1,0,0);

(9)
\begin{align} \left[ \begin{array}{cc} 1 & 0 & 0 & 0 \\ 0 & cosa & -sina & 0 \\ 0 & sina & cosa & 0 \\ 0 & 0 & 0 & 1\\ \end{array} \right] \end{align}

glRotatef(a,0,1,0);

(10)
\begin{align} \left[ \begin{array}{cc} cosa & 0 & sina & 0 \\ 0 & 1 & 0 & 0 \\ -sina & 0 & cosa & 0 \\ 0 & 0 & 0 & 1\\ \end{array} \right] \end{align}

glRotatef(a,0,0,1);

(11)
\begin{align} \left[ \begin{array}{cc} cosa & -sina & 0 & 0 \\ sina & cosa & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1\\ \end{array} \right] \end{align}

参考書籍

red.jpgOpenGLプログラミングガイド 原著第5版
camera math matrix opengl

サポートサイト Wikidot.com cameramathmatrixopengl