• ベストアンサー

3D→2Dの座標変換で、スクリーン(カメラ)の後ろの判定ができるか

こんにちは。 3Dの座標を2Dのスクリーン座標に変換するには screen.x = Projection * world.x / world.z; screen.y = Projection * world.y / world.z; でいいと思うのですが、 問題は、その3D座標がスクリーン(カメラ)の後ろ側に なってしまった時にその判定をしたいと思っています。 このままでは、カメラの後ろ側にその3D座標があっても、 2Dの位置は変わりません。 どのように計算すればよろしいのでしょうか? よろしくお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
  • kmb01
  • ベストアンサー率45% (63/138)
回答No.1

>screen.x = Projection * world.x / world.z; >screen.y = Projection * world.y / world.z; このやり方だとworld.z<0がカメラの後ろ側の条件になるはず。 カメラ位置(0,0,0)、カメラ方向(0,0,1)で固定ということだと判断しました。 カメラの移動とかを考えるなら、 カメラの位置と方向からワールド座標をカメラ座標に変換、 投影モード(平行投影、透視投影)のパラメータからカメラ座標をビュー座標に変換、 スクリーンサイズからビュー座標をスクリーン座標に変換、 といった処理を行います。

majikaru
質問者

お礼

ご返答ありがとうございます。 >このやり方だとworld.z<0がカメラの後ろ側の条件になるはず。 カメラ位置(0,0,0)、カメラ方向(0,0,1)で固定ということだと判断しました。 すみません。記述し損ねていました。 自分が行いたい処理はカメラの位置座標と向きは常に変化するので Z座標を頼りにカメラの後方を判別できない条件なのです。 >カメラの移動とかを考えるなら、 カメラの位置と方向からワールド座標をカメラ座標に変換、 投影モード(平行投影、透視投影)のパラメータからカメラ座標をビュー座標に変換、 スクリーンサイズからビュー座標をスクリーン座標に変換、 といった処理を行います。 こちらは具体的にどういった処理になりますでしょうか? 例や計算式を出して頂けると助かるのですが…。 どうぞよろしくお願いします。

その他の回答 (1)

  • kmb01
  • ベストアンサー率45% (63/138)
回答No.2

単にカメラの前後を調べるだけなら、(カメラ位置から調べる点までのベクトル)と(カメラの向きベクトル)の内積の正負でわかりますが、カメラ位置から点がどのように見えるかが分かりません。やはりカメラ変換行列を求めるのがいいと思います。 例えば、 ワールド座標で点A(10,0,0), B(0,10,0), C(0,0,10), O(0,0,0)があり、これをカメラ位置E(100,100,80), カメラ注視点R(0,0,0)のカメラで見たとき、 カメラ奥向きベクトル vec_z = R - E = (-100, -100, -80) -> (-0.62, -0.62, -0.49) このvec_zを元にカメラの右向きベクトルと上向きベクトルを求める。仮の上向きベクトルをU(0,0,1)とすると カメラ右向きベクトル vec_x = (奥向きベクトルと上向きベクトルの外積(左手系)) = (-0.71, 0.71, 0) カメラ上向きベクトル vec_y = (右向きベクトルと奥向きベクトルの外積(左手系)) = (-0.35, -0.35, 0.87) カメラ変換行列Mは、 [-0.71 -0.35 -0.62 0] [-0.71 -0.35 -0.62 0] [ 0 0.87 -0.49 0] [ ? ? ? 1] となり、カメラ座標ではカメラ位置Eが(0,0,0)になることから、E*M=(0,0,0,1)となるように?を求めて、 M = [-0.71 -0.35 -0.62 0] [-0.71 -0.35 -0.62 0] [ 0 0.87 -0.49 0] [ 0 0 162.48 1] これにより、点Aをこのカメラで見たとき、A*M = (-7.1, -3.5, 156.3, 1)のように見えると分かります。 同様 B*M = (7.1, -3.5, 156.3) C*M = (0, 8.7, 157.6) O*M = (0, 0, 162.48)

参考URL:
http://homepage2.nifty.com/skimp-studio/htm/crawl/1_9_transform4.htm