SSブログ

Mac用プロットライブラリ-18「3次元プロットの問題点整理」 [考え中 - プロットライブラリ]

三連休で横浜に帰っている。前回までで2次元の一番大きな問題だったはみ出しの扱いに一段落ついたので、今度は3次元の問題点をこれから整理しよう。

前にも書いたように3次元グラフは

  1. 2次元と同様にAutomaticオプションを展開して3次元のPrimitiveの集合に変換する
  2. 3次元のNormalized座標に変換する
  3. 射影変換を行い、2次元のPrimitiveの集合に変換する
  4. それを2次元PrimitiveレイヤとしてViewレイヤまで展開し描画する
ということを行う。さらに付加的な作業
  1. 隠面処理
  2. 疑似照明の処理
  3. 2次元Primitveの3次元上の平面への貼付け
などがある。

もう少し詳細を整理する。

Mathematicaでの取り扱い

このライブラリでは3次元描画もMathematicaになるべく外から見える動作を合わせたい、と考えている。Mathematicaの3次元描画はOpenGLなどの考え方と違っているところがあるので、ここで整理しておく。

Mathematicaでも3次元の位置情報に射影変換(例えばここなどを参考に)をほどこして2次元にして描画するのは同じのようである。3次元座標の取り方が、OpenGLなどはz方向が奥行き方向になっているが、Mathematicaではデフォルトでz軸方向は上に取られる。ただし、どちらも右手系で表示される。

0720axes.png

Mathematicaのドキュメントに座標変換に関する記述はないが、Graphics3Dの持っているオプションからどうなっているかを見てみる。

「スケールされた座標」

Mathematicaの3次元描画では2次元と同じように「スケールされた座標」というのが使われる。内部的にこのまま使う必要はないが、いちおうこれに従うことにする。BoxRatios(3次元の場合のAspectRatioに対応する)が指定されていないとき、x,y,z全部の座標が(0,1)に規格化される。また、BoxRatioが指定されている場合、最も長い座標軸が(0,1)になるように規格化される。

これを「スケールされた座標」とMathematicaでは呼んでいる。カメラや視点位置はこの座標系で指定することになる。

ViewPointとViewCenter、ViewVertical

Mathematicaではカメラ位置のことをViewPointと呼んでいる。また、そのカメラがどこを向かって見ているか、その視野の中心をViewCenterで表す。どちらも3次元のリストで前述の「スケールされた座標」で表現している。

0720viewpoint.png

ただしややこしいことに、ViewPointは視野の中心を(0,0,0)と見なしている。だから視線の方向は

-ViewPoint
になるらしい。そしてViewCenterは「スケールされた座標」のどの位置を視野の中心に置くか、を指定するのでその「スケールされた座標」でのカメラ位置は
ViewCenter + ViewPoint
になるはず。なんでこうなっているのかはわからない。

ViewPointのデフォルトは(1.300, -2.400, 2.000)で、ViewCenterはデフォルトで(0.5,0.5,0.5)になっているらしい。

また、ViewVerticalというオプションがあって、視線の方向に対してどちらを上にとるか、を指定する。デフォルトでは(0,0,1)(z軸の正の方向)になっている。

OpenGLの場合、この辺の扱いはgluLookAt()なんかでやってることに対応する。

SphericalRegion

MathematicaにはさらにSphericalRegionというオプションがある。これをTrueに指定すると、中心が境界ボックスの中心に一致して境界ボックスに外接する球を考え、それが最終的な描画領域いっぱいに表示されるようになる。

0720sphericalregion.png

Mathematicaの3次元プロットのデフォルトでは、最終的な2次元描画領域いっぱいに表示されるように拡大縮小されるが、例えば細長いオブジェクトをプロットするとき、見る方向(長手を手前奥に見るか、横に見るか)によって大きさが変わる。これはそのオブジェクトの周りをぐるぐる回るようなアニメーションを描こうとしたとき、大きさがくるくる変わることになって煩わしい。

SphericalRegionをTrueにすれば向きによらず一定の縮尺で描画されることになるのでアニメーションには都合がいい。

SphericalRegionを表現するにはその球を、表示されないオブジェクトとしてプロットオブジェクトに含めてしまえばよい。

「表示されないオブジェクト」というのはこれまで考えてなかったけど、一番簡単な方法はOpacity(不透明度)が0のオブジェクトにしてしまうのが手っ取り早い。しかしその場合、最終的に描画されないだけで、ほかのオブジェクトと全く同じ処理をしなければいけない。これは無駄が多いけど、とりあえずまあいいでしょ。実装のところでもうちょっとまじめに考えよう。

Mathematicaがやってることのおさらいはこんなもんか。これをなるべく同じ振る舞いになるようにしたい。その他にももうちょっとあるので、それを次回。


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

nice! 0

コメント 0

コメントを書く

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

トラックバック 0

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