SSブログ

Mac用プロットライブラリ-19「Normalized座標と射影変換」 [考え中 - プロットライブラリ]

もう榴岡に戻ってきた。
昨日からプロットライブラリの3次元プロットの問題を整理し始めた。特に3次元プロットではMathematicaと動作を似せようとしたときに意識する必要のあるところを整理していく。次は3次元プロットでの座標の規格化と射影変換について。

3次元Normalized座標

MathematicaではViewPoint、ViewCenter、ViewVerticalを使って射影変換のマトリクスを作っているらしいということを昨日整理した。おそらく

  1. 3次元オブジェクトの集合から境界ボックスの大きさを決める
  2. オブジェクトを「スケールされた座標」で表現する
  3. ViewPoint、ViewCenter、ViewVerticalを使って射影変換のマトリクスを作る
  4. 3次元のオブジェクトを変換して2次元のオブジェクトにする
  5. それを2次元の「スケールされた座標」にさらにマップする。このとき必ず縦横比は保存する
  6. 描画を行う
としているようである。このライブラリでも同じ方向でやろうと思う。つまり昨日言及したMathematicaの「スケールされた座標」を、このライブラリの「3次元Normalized座標」と同じものと見なすことにする。

このとき、射影変換をほどこした結果が、必ずしも2次元Normalized座標としてそのまま使えるわけではないし、なるべく2次元の描画と共通にできるようにしたい。ということで2次元の場合Normalized座標は単精度(float)を使ったが、3次元では

  • 3次元プリミティブ
  • 3次元Normalized座標で表現されたプリミティブ
  • 射影変換後の2次元になったオブジェクト
はすべて倍精度(double)のままにする。精度的には全く無駄だけどこうすると射影変換後のオブジェクトは2次元プリミティブとしてそのまま使える。何度も座標変換をすることになるけど、なるべくそれぞれのレイヤでの作業をシンプルにできるであろうと期待してこうしておくことにする。実際に実装を始めて無駄が多いというのがわかれば、もう一度考え直すことにする。

射影変換

Mathematicaが行っている射影変換の詳細はわからない。しかし、見た目が同じになるように射影変換を設定することはできる。
考えられる手順は以下のようである。

  1. ViewCenterが原点にくるようにオブジェクトを平行移動する
  2. ViewPointの方向がz軸になるように回転する
  3. ViewVerticalがy軸の正の方向を向くようにz軸の周りに回転する
  4. 新しいz軸に直行する適当な平面をスクリーンにする
  5. カメラ位置からスクリーンに射影する
とすればよい。これは最終的には4×4の射影変換マトリクス一つで表現できる。

3次元オブジェクトは少なくともNormalized座標の(0,0,0) - (1,1,1)の中に入っているはずなので遠くのオブジェクトやクリッピングの神経質な取り扱いは必要ない。ただし、ViewPointの指定の仕方によってはスクリーンに射影されない場合があるので注意を要する。

0721fig4.png

普通OpenGLなどでは、図-4のように、描画オブジェクトとカメラの間にスクリーンを配置する(遠くの点を含めて射影するにはそうするしかない)。カメラはスクリーンを透かしてオブジェクトを見ていることになる。

しかし今回の場合、ViewPointの設定によってはオブジェクトとの間にうまくスクリーンを配置できない(たとえばViewPointが描画領域の内部にある)場合もありえる。そこで、図-5のようにスクリーンをオブジェクトの背後に配置することにする。

0721fig5.png

スクリーンへは、こんどはオブジェクトを通して射影する。
こうすれば、今回の場合描画対象になるオブジェクトは3次元Normalized座標では奥の遠くの方にあることはないので、3者の関係をあまり悩まなくてすむ。例えば回転を施した後の座標で原点から奥に「2」行ったところにスクリーンをおけば射影可能なオブジェクトは必ずスクリーンの上に変換できる。今回の場合、これで十分であり、スクリーンの位置は最終的な描画に影響はない。

変換の具体的なマトリクスの中身や、その構成法なんかは方針が決まってしまえばそれほど難しくはないのであとから考える。このあたりの数学は3Dゲームのおかげでずいぶん一般的になっている。あまり悩まないことにしよう。

次は、OpenGLや3Dゲームではあまり問題にならない(ハードがやる)隠面処理について。これは結構つらいかも。


nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。