質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

Q&A

解決済

2回答

1589閲覧

法線を求める際に出てきた関数、の内容がわかりません。

seri

総合スコア422

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

0グッド

1クリップ

投稿2017/01/18 16:03

mat4 makeLookAt(vec3 eye, vec3 center, vec3 up) { mat4 M; vec3 zaxis = normalize(eye - center); vec3 xaxis = normalize( cross(up, zaxis) ); vec3 yaxis = cross(zaxis,xaxis); M[0] = vec4(xaxis,0); M[1] = vec4(yaxis,0); M[2] = vec4(zaxis,0); M[3] = vec4(eye,1); return M; }

とゆう関数でして
これがどういった処理をしてくれているのか理解できません。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

私3Dのことは全然知らないのですがこのプログラム見てものすごく勉強になりましたので、何を読み取れたかをお伝えします。

最後から読んでいきます。
Mという値を返していますが、これが4×4の行列です。4×4の行列って何かというと、3次元のアフィン変換です。
アフィン変換という言葉、ご存じなかったなら私の昔書いた記事なんですがこちらの解説どうぞ→ アフィン変換/平行移動だって変換行列で
回転・各方向の拡大縮小・水平移動とそれらの自由な順番での組み合わせを4×4の行列で一発記述できますよってのがアフィン変換です。

そう、直線をアフィン変換で表現しようとしているのです。

中学ぐらい数学で直線の式ってどう習いましたっけ。

ax + by + c = 0

の形で表現できるよと習いました(y=ax+bだと不十分です。これだと垂直な線が表現できませんので)。
これは平面上、二次元の直線なのですが、じゃあ、三次元に拡張したら

ax + by + cz + d = 0

の形でいいのかというと、これ違うんですよね。この式は、三次元空間内の平面の式になってしまうんです。じゃあ三次元の直線の表し方は、っていうと、「えーと、ベクトルとその基点座標の組み合わせで表したら?」くらいしか知りませんでした。でもアフィン変換で表すの、これ美しいです。
Z軸という直線をうまく回転して水平移動すれば、三次元空間内の任意の直線を表せます。その「うまく回転して水平移動する」操作を4×4の行列で表現しているわけ。M[3]のはじめの要素が水平移動量を表しています。そこにeyeを使っていますから、ちょうど眼の座標へ移動しているんだと読み取れます。M[0], M[1], M[2]のそれぞれはじめの3要素で回転を表現しているのですが、ここは何をどう指定したらどういう回転を意味するのかは不勉強でちゃんと説明できません。

ただ、xaxis, yaxis, zaxisというのが何を意味しているベクトルかまでだったら説明できます。

まずこれら3つはお互いに直角で長さが1のベクトルです。フレミングの右手とか左手の法則の親指・人差し指・中指状態ですよ。で、全部長さが1。単位ベクトル。
アフィン変換の回転表現部分にこの三本指をぶち込むと、どうやらちょうどその三本指にあうように回転してくれるって言ってるように読めます。というかそうとしか読めません。

三本指を一本ずつ読んでいきます。
zaxis、これは視線方向です。長さ1の
(eye-center)、これで視線方向のベクトルが取れますから、それをnormalizeして長さ1にしているだけですね。
xaxis、これは主人公の真横方向です。えっと真右になるのかな真左になるのかな、忘れちゃったけどどっちでもいいです。この主人公には視線方向だけでなく頭頂がどっち向いているという方向ベクトル(up)があるので、これと視線方向の外積(cross)をとっています。外積up×zaxisは、upともzaxisとも直角となるベクトルになる(右向きだか左向きだか忘れたけど)ので、つまりほっぺた方向、真横となります。
yaxisは視線・ほっぺた方向両方と直角となる、上方向のベクトルです。上方向って頭頂向きのupがあったじゃない、っていうとそうなんですけど、「見下ろして」いたり「見上げて」いたり、つまり視線方向と頭頂方向が直角じゃないときにいっちしなくなりますので。

とはいえここで一番大事なのはzaxis、視線方向で、Z軸がこのzaxis方向に向くような回転するんだよ、それをeyeの位置まで平衡移動するんだよ、そうして表される直線が法線だよ、という意図がこのプログラムから読み取れました。
おやすみなさい。

投稿2017/01/18 17:26

yuba

総合スコア5568

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

変数名と演算内容からの推測です(ちなみにこれGLSLという言語でしょうか?)

crossはベクトルの外積、normalizeは正準化(つまり方向が同じの単位ベクトルへの変換)だとすると・・・

ある座標系Sにおいて

eyeはカメラの視点を表すS上での位置ベクトル
centerはカメラの注視点を表すS上での位置ベクトル
upは「上をどっちにするかを決めるための」S上での方向ベクトル

と考えます。そして別の座標系S'を考えます。S'の座標は以下のように考えます。

  • Z軸

カメラの注視点からカメラの視点方向

  • Y軸

upの方向に概ねあっていてZ軸と垂直な方向。なんだかテキトーな表現ですがカメラの視点からみてupベクトルとY軸がちょうど重なるように見えてかつZ軸に垂直という条件を満たすような方向という意味になると思います。

  • X軸

Z軸とY軸に垂直な方向

  • 原点

カメラの視点

結果のM(4x4の行列)は座標系S'上の位置ベクトルを座標系S上の位置ベクトルへの写像を表す変換行列になると思います。

M[i]が数学でいうi行のことだとすれば、座標系S'上の位置ベクトルv'を(x', y', z', 1)と表すことにして、

v = v' * M

と計算して求まるvは座標系S上の位置ベクトルになるという感じです。

GLSLの座標系の前提などがわからないので若干差異があるかも知れませんが意味的には概ね以上のようなものだと思います。


追記:一つ忘れてました。カメラの視線方向とupベクトルが平行だと結果は正しく求まりません。
S'座標系のX軸を計算する外積の結果が0ベクトルになるからです。(浮動小数演算だとすれば計算誤差に救われて誤差によって決まる適当な方向がX軸になったりするかも知れませんがw;)

投稿2017/01/18 17:29

編集2017/01/18 17:43
KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問