Mac用プロットライブラリ-19「Normalized座標と射影変換」 [考え中 - プロットライブラリ]
昨日からプロットライブラリの3次元プロットの問題を整理し始めた。特に3次元プロットではMathematicaと動作を似せようとしたときに意識する必要のあるところを整理していく。次は3次元プロットでの座標の規格化と射影変換について。
3次元Normalized座標
MathematicaではViewPoint、ViewCenter、ViewVerticalを使って射影変換のマトリクスを作っているらしいということを昨日整理した。おそらく
- 3次元オブジェクトの集合から境界ボックスの大きさを決める
- オブジェクトを「スケールされた座標」で表現する
- ViewPoint、ViewCenter、ViewVerticalを使って射影変換のマトリクスを作る
- 3次元のオブジェクトを変換して2次元のオブジェクトにする
- それを2次元の「スケールされた座標」にさらにマップする。このとき必ず縦横比は保存する
- 描画を行う
このとき、射影変換をほどこした結果が、必ずしも2次元Normalized座標としてそのまま使えるわけではないし、なるべく2次元の描画と共通にできるようにしたい。ということで2次元の場合Normalized座標は単精度(float)を使ったが、3次元では
- 3次元プリミティブ
- 3次元Normalized座標で表現されたプリミティブ
- 射影変換後の2次元になったオブジェクト
射影変換
Mathematicaが行っている射影変換の詳細はわからない。しかし、見た目が同じになるように射影変換を設定することはできる。
考えられる手順は以下のようである。
- ViewCenterが原点にくるようにオブジェクトを平行移動する
- ViewPointの方向がz軸になるように回転する
- ViewVerticalがy軸の正の方向を向くようにz軸の周りに回転する
- 新しいz軸に直行する適当な平面をスクリーンにする
- カメラ位置からスクリーンに射影する
3次元オブジェクトは少なくともNormalized座標の(0,0,0) - (1,1,1)の中に入っているはずなので遠くのオブジェクトやクリッピングの神経質な取り扱いは必要ない。ただし、ViewPointの指定の仕方によってはスクリーンに射影されない場合があるので注意を要する。
普通OpenGLなどでは、図-4のように、描画オブジェクトとカメラの間にスクリーンを配置する(遠くの点を含めて射影するにはそうするしかない)。カメラはスクリーンを透かしてオブジェクトを見ていることになる。
しかし今回の場合、ViewPointの設定によってはオブジェクトとの間にうまくスクリーンを配置できない(たとえばViewPointが描画領域の内部にある)場合もありえる。そこで、図-5のようにスクリーンをオブジェクトの背後に配置することにする。
スクリーンへは、こんどはオブジェクトを通して射影する。
こうすれば、今回の場合描画対象になるオブジェクトは3次元Normalized座標では奥の遠くの方にあることはないので、3者の関係をあまり悩まなくてすむ。例えば回転を施した後の座標で原点から奥に「2」行ったところにスクリーンをおけば射影可能なオブジェクトは必ずスクリーンの上に変換できる。今回の場合、これで十分であり、スクリーンの位置は最終的な描画に影響はない。
変換の具体的なマトリクスの中身や、その構成法なんかは方針が決まってしまえばそれほど難しくはないのであとから考える。このあたりの数学は3Dゲームのおかげでずいぶん一般的になっている。あまり悩まないことにしよう。
次は、OpenGLや3Dゲームではあまり問題にならない(ハードがやる)隠面処理について。これは結構つらいかも。
コメント 0