ポリゴンレンダラ - その3 [プログラミング]
効率的なPDFベースのポリゴンのレンダラを実装しようとしている。今回は効率優先なので前回MathematicaのGraphicsComplexというデータ構造をパクることにした。最初からあまり実装に近いところに突っ込むとぐちゃぐちゃになって投げ出すということになりかねないので、注意しないといけない。
今日はまた座標変換のための専用の数学をまとめておく。特に目新しいことはなくて、どうしても退屈なベクトルを使った幾何学の話になるけど、これをやっておかないと実装のときにやっぱりぐちゃぐちゃになってしまうのでやっておく。
3次元のモデルの座標系を(x,y,z)とする。viewPointの座標をp=(px,py,pz)、viewCenterの座標をc=(cx,cy,cz)とする。
また図-2のように、2次元の座標系を(u,v)とする。uの正の方向を右、vの正を上にとる。補助的にwを考えて(u,v,w)で3次元座標とする。(u,v,w)の原点は視点の位置にある、とする。 (x,y,z)から(u,v)への射影変換は、幾何学的に考えれば
しかし普通は同次座標を使ったマトリクスのかけ算で表すことの方が多い。同次座標を使う方が機械的にできるので計算機で数値計算するのに便利なためで、実質的な計算量は平面と直線の交点を求める方法と変わらない。
ここでは最終的に同次座標を使って射影変換ができるようにする。実装することを考えて、同次座標のマトリクスを得るための回転のマトリクスの決定を順を追ってまとめておく。
まず、最初は(x,y,z)と(u,v,w)が一致していたとして、視線の方向がwの負の方向に、viewVerticalがv−w平面内でvが正の方向に一致させるように、もとの3次元モデルの座標を回転させる。
一般の方向を向いたベクトルをある方向に向ける回転のマトリクスを直接書き下すのは難しい。そこで、軸の周りの回転をいくつか組み合わせて最終的なマトリクスを得る、と言うことをする。
軸の周りの回転を組み合わせると言っても、何通りもやり方がある。ここでは
どんなやりかたをしても同次座標のマトリクスは同じになるし、ベクトルを回転させるときに回転軸と一致していないかどうかの判定は必ず必要なので、たまたま今回はこうする、というだけである。
視線の方向のベクトルをkとすると である。これをd=(du,dv,dw)=(0,0,−1)と一致するように回転させる。そのためにはkとdを含む平面を考えてPとする。Pの規格化されていない法線ベクトルnは である。ここで×の記号はベクトル積を表す。
回転が簡単になるように2段階にわける。つまりまずnをv=(0,1,0)に一致させるようにdのまわりに回転させてPをu−w面と一致させ、そのあとvのまわりに回転させてkをdに一致させる。
dのまわりに角度ϕだけ回転させるマトリクスをAd(ϕ)とすると(めんどうなので、縦ベクトルも横ベクトルと同じ書き方をする。これはMathematicaの慣例と同じ。Mathematicaの場合は横ベクトルと縦ベクトルは違う構造を表すことになるのでそうなっているんだけど、僕の場合はただLaTeXを書くのが面倒だからと言うだけ) であるが、 nとvのなす角をϕとすると と書けるので、回転のマトリクスの要素は、三角関数を計算しなくてもすむ。符号に注意しないといけない。
ここまでベクトルを成分であらわに書かずにきたけど、実はdやvが軸に平行なので、 と簡単になってしごくあたりまえの結論になる。
そんなの見ればわかるじゃん、というのは、確かにその通り。実は後から気がついた。
今日はまた座標変換のための専用の数学をまとめておく。特に目新しいことはなくて、どうしても退屈なベクトルを使った幾何学の話になるけど、これをやっておかないと実装のときにやっぱりぐちゃぐちゃになってしまうのでやっておく。
3.1 座標変換
前々回扱う座標系を考えた。3次元のモデルを2次元の絵として表示するためのいくつかの約束を決めた。今日はその3次元から2次元に落とすための作業(射影変換)を座標変換とみなして具体的な変換行列を求めておく。3次元のモデルの座標系を(x,y,z)とする。viewPointの座標をp=(px,py,pz)、viewCenterの座標をc=(cx,cy,cz)とする。
また図-2のように、2次元の座標系を(u,v)とする。uの正の方向を右、vの正を上にとる。補助的にwを考えて(u,v,w)で3次元座標とする。(u,v,w)の原点は視点の位置にある、とする。 (x,y,z)から(u,v)への射影変換は、幾何学的に考えれば
- pから変換したい点(ax,ay,az)への直線を考える
- (u,v,w)の原点を通らない(u,v)平面に平行な平面を考える
- 平面と直線の交点を求める
しかし普通は同次座標を使ったマトリクスのかけ算で表すことの方が多い。同次座標を使う方が機械的にできるので計算機で数値計算するのに便利なためで、実質的な計算量は平面と直線の交点を求める方法と変わらない。
ここでは最終的に同次座標を使って射影変換ができるようにする。実装することを考えて、同次座標のマトリクスを得るための回転のマトリクスの決定を順を追ってまとめておく。
3.2 座標回転
3次元のモデル座標(x,y,z)をいったん(u,v,w)に変換して、その内部で射影を行って最終的な(u,v)の2次元座標を得る、というふうに考える。まず、最初は(x,y,z)と(u,v,w)が一致していたとして、視線の方向がwの負の方向に、viewVerticalがv−w平面内でvが正の方向に一致させるように、もとの3次元モデルの座標を回転させる。
一般の方向を向いたベクトルをある方向に向ける回転のマトリクスを直接書き下すのは難しい。そこで、軸の周りの回転をいくつか組み合わせて最終的なマトリクスを得る、と言うことをする。
軸の周りの回転を組み合わせると言っても、何通りもやり方がある。ここでは
- 視線の方向のベクトルがu−w平面内にあるようにw軸周りに回転
- 視線の方向がwの負の方向を向くようにv軸周りに回転
- viewVerticalのu成分が0になるようにw軸周りに回転
どんなやりかたをしても同次座標のマトリクスは同じになるし、ベクトルを回転させるときに回転軸と一致していないかどうかの判定は必ず必要なので、たまたま今回はこうする、というだけである。
視線の方向のベクトルをkとすると である。これをd=(du,dv,dw)=(0,0,−1)と一致するように回転させる。そのためにはkとdを含む平面を考えてPとする。Pの規格化されていない法線ベクトルnは である。ここで×の記号はベクトル積を表す。
回転が簡単になるように2段階にわける。つまりまずnをv=(0,1,0)に一致させるようにdのまわりに回転させてPをu−w面と一致させ、そのあとvのまわりに回転させてkをdに一致させる。
dのまわりに角度ϕだけ回転させるマトリクスをAd(ϕ)とすると(めんどうなので、縦ベクトルも横ベクトルと同じ書き方をする。これはMathematicaの慣例と同じ。Mathematicaの場合は横ベクトルと縦ベクトルは違う構造を表すことになるのでそうなっているんだけど、僕の場合はただLaTeXを書くのが面倒だからと言うだけ) であるが、 nとvのなす角をϕとすると と書けるので、回転のマトリクスの要素は、三角関数を計算しなくてもすむ。符号に注意しないといけない。
ここまでベクトルを成分であらわに書かずにきたけど、実はdやvが軸に平行なので、 と簡単になってしごくあたりまえの結論になる。
そんなの見ればわかるじゃん、というのは、確かにその通り。実は後から気がついた。
2013-04-01 21:30
nice!(0)
コメント(0)
トラックバック(0)
コメント 0