お世話になります。
実例で学ぶゲーム3D数学
リンク先の本を読んでいてて思ったことが1つ、質問が1つあります。
まず、思ったことは、リンク先の本の 第9章 3Dにおける方向と角変位 で、3つの角変位を紹介しています。
1.行列を使った角変位
2.オイラー角を使った角変位
3.4元数を使った角変位
それぞれ、長所と短所があるのはわかりました。
しかし、Dxライブラリでは、行列を使った関数しかありません。
つまり、いまのところは、DirectX 9.0c くらい(?)では行列を使った角変位しかサポートしていない
ということになるのでしょうか?
2と3は、読んでいてて確かに難しくて、単純によみすすめれるものではありませんでした。
実際に、使う数学的な知識としては、1の行列を使った角変位のみを理解しておけば、
Dxライブラリにおいては、不自由しないということでしょうか?
次に質問です。
DirectX Graphicsでは、ワールド座標に物体があると仮定して、
モデル空間のベクトル「v」を、スクリーン空間に変換したベクトル「v’」を導き出すには、
v’ = ワールド行列 x ビュー行列 x 射影行列 x ビューポート行列
となっています。
ここでは、すべて行列で、計算がすんでいるので、問題ないのですが、言葉の定義が、
本の作者や、書かれた年代で、微妙に変化しているので、なかなかパッとしません。
そこで、とてもモヤモヤしているのですが、このモヤモヤをはっきりとしたものとするには
どういったアプローチをとるのがいいのでしょうか?
まだ、3Dのプログラムをきちんと理解して、組めていない私にとっては、
どういった手順で、理解していくのがおすすめでしょうか?
なんか、高校受験のどういった勉強が効率的でしょうか?というような質問になってしまいますが、
なかなか、私では突破口がみつからないので、手助けをお願いします。
3Dにおける角度の表現について
Re: 3Dにおける角度の表現について
O'Reillyの公式サイトに第9章のPDFがあったので貼っておきます。
ftp://ftp.oreilly.co.jp/9784873113777/g3d_sample03.pdf
コンピューターにとっては行列による回転しか直接は処理できないということです。
しかしながら、オイラー角や四元数による角度の表現から行列に変換することは可能です。
ですから最終的に行列になっていれば良いというだけです。
DXライブラリに行列を使った関数しか存在しないというのは間違いです。
DXライブラリの関数は基本的に「オイラー角」で角度を指定しています。
例えば、MGetRotXはオイラー角から行列に変換するための関数です。
MV1SetRotationXYZでは内部的にオイラー角が行列に変換されています。
オイラー角のほうが分かりやすいはずなので、1は理解できるのに2が理解出来ないというのはちょっとおかしな話です。
DXライブラリの角度指定はオイラー角なのでそれを知っていればいいことになります。
四元数は角度の線形補間を行いたい場合に便利ですがあまり直感的ではありません。
DXライブラリにはないかもしれませんが、DirectXにはAPIが用意されています。
知らなくてもいちおう3Dプログラミングはできます。
「実例で学ぶゲーム3D数学」の内容を理解していればDXライブラリなしでも3Dプログラミングできますが、
いまそれを目標にしなくても良いと思います。
ftp://ftp.oreilly.co.jp/9784873113777/g3d_sample03.pdf
DirectXというよりもハードウェアの都合上、3Dにおける回転については基本的に行列しか使えません。dic さんが書きました: 1.行列を使った角変位
2.オイラー角を使った角変位
3.4元数を使った角変位
それぞれ、長所と短所があるのはわかりました。
しかし、Dxライブラリでは、行列を使った関数しかありません。
つまり、いまのところは、DirectX 9.0c くらい(?)では行列を使った角変位しかサポートしていない
ということになるのでしょうか?
コンピューターにとっては行列による回転しか直接は処理できないということです。
しかしながら、オイラー角や四元数による角度の表現から行列に変換することは可能です。
ですから最終的に行列になっていれば良いというだけです。
DXライブラリに行列を使った関数しか存在しないというのは間違いです。
DXライブラリの関数は基本的に「オイラー角」で角度を指定しています。
例えば、MGetRotXはオイラー角から行列に変換するための関数です。
MV1SetRotationXYZでは内部的にオイラー角が行列に変換されています。
- MGetRotX
- MGetRotY
- MGetRotZ
- MGetRotAxis
- MGetRotVec2
- MV1SetRotationXYZ
「実例で学ぶゲーム3D数学」に書かれているとおり、行列による回転は人間にとっては直感的ではありません。dic さんが書きました: 2と3は、読んでいてて確かに難しくて、単純によみすすめれるものではありませんでした。
実際に、使う数学的な知識としては、1の行列を使った角変位のみを理解しておけば、
Dxライブラリにおいては、不自由しないということでしょうか?
オイラー角のほうが分かりやすいはずなので、1は理解できるのに2が理解出来ないというのはちょっとおかしな話です。
DXライブラリの角度指定はオイラー角なのでそれを知っていればいいことになります。
四元数は角度の線形補間を行いたい場合に便利ですがあまり直感的ではありません。
DXライブラリにはないかもしれませんが、DirectXにはAPIが用意されています。
ビュー行列とか四元数とかの知識はDXライブラリを使っている以上はあまり重要ではありません。dic さんが書きました: DirectX Graphicsでは、ワールド座標に物体があると仮定して、
モデル空間のベクトル「v」を、スクリーン空間に変換したベクトル「v’」を導き出すには、
v’ = ワールド行列 x ビュー行列 x 射影行列 x ビューポート行列
となっています。
ここでは、すべて行列で、計算がすんでいるので、問題ないのですが、言葉の定義が、
本の作者や、書かれた年代で、微妙に変化しているので、なかなかパッとしません。
そこで、とてもモヤモヤしているのですが、このモヤモヤをはっきりとしたものとするには
どういったアプローチをとるのがいいのでしょうか?
まだ、3Dのプログラムをきちんと理解して、組めていない私にとっては、
どういった手順で、理解していくのがおすすめでしょうか?
知らなくてもいちおう3Dプログラミングはできます。
「実例で学ぶゲーム3D数学」の内容を理解していればDXライブラリなしでも3Dプログラミングできますが、
いまそれを目標にしなくても良いと思います。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: 3Dにおける角度の表現について
DirectX9にはありますよ。dic さんが書きました:お世話になります。
実例で学ぶゲーム3D数学
リンク先の本を読んでいてて思ったことが1つ、質問が1つあります。
まず、思ったことは、リンク先の本の 第9章 3Dにおける方向と角変位 で、3つの角変位を紹介しています。
1.行列を使った角変位
2.オイラー角を使った角変位
3.4元数を使った角変位
それぞれ、長所と短所があるのはわかりました。
しかし、Dxライブラリでは、行列を使った関数しかありません。
つまり、いまのところは、DirectX 9.0c くらい(?)では行列を使った角変位しかサポートしていない
ということになるのでしょうか?
2と3は、読んでいてて確かに難しくて、単純によみすすめれるものではありませんでした。
実際に、使う数学的な知識としては、1の行列を使った角変位のみを理解しておけば、
Dxライブラリにおいては、不自由しないということでしょうか?
「その10 クォータニオンを学んでみよう!」
http://marupeke296.com/DXG_No10_Quaternion.html
まぁ、クォータニオンは自分で作れるので必要なら実装すれば良いだけです。
4元数を使わないと解決できないカメラなどの動きも有るので、必要に応じてという感じでしょうか。
ジンバルロックを防ぐ必要がある場合に使います。
すごく大雑把に言うとdic さんが書きました: 次に質問です。
DirectX Graphicsでは、ワールド座標に物体があると仮定して、
モデル空間のベクトル「v」を、スクリーン空間に変換したベクトル「v’」を導き出すには、
v’ = ワールド行列 x ビュー行列 x 射影行列 x ビューポート行列
となっています。
ここでは、すべて行列で、計算がすんでいるので、問題ないのですが、言葉の定義が、
本の作者や、書かれた年代で、微妙に変化しているので、なかなかパッとしません。
そこで、とてもモヤモヤしているのですが、このモヤモヤをはっきりとしたものとするには
どういったアプローチをとるのがいいのでしょうか?
まだ、3Dのプログラムをきちんと理解して、組めていない私にとっては、
どういった手順で、理解していくのがおすすめでしょうか?
なんか、高校受験のどういった勉強が効率的でしょうか?というような質問になってしまいますが、
なかなか、私では突破口がみつからないので、手助けをお願いします。
モデルのワールドとローカルの変換系さえ理解していれば大抵は大丈夫です。
あとは雰囲気を掴めばよいだけなんですよ。
ビュー行列は、要するにカメラの前に世界を回して並べる行為です。イメージ的にはカメラを動かすと言ったほうが良いでしょうね。
射影行列は、カメラのレンズのようなものです。透視投影して2D座標系に変換を行います。世界→カメラレンズ→フォルムですね。
ビューポート行列は座標系を合わせるのに使うだけです。 射影変換後は画一の単位なので640x480やら1280x780やらスクリーンの座標系に変換します。
といった感じだと思います。色々本やAPIなどで用語が違ったりするので間違っていたらごめんなさい。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: 3Dにおける角度の表現について
例えを思いついたので書いておきます。
(1)ビュー行列は、要するにカメラの前に世界を回して並べる行為です。イメージ的にはカメラを動かすと言ったほうが良いでしょうね。
すきなアングルで一眼レフカメラを構えます。
(2)射影行列は、カメラのレンズのようなものです。透視投影して2D座標系に変換を行います。世界→カメラレンズ→フォルムですね。
広角やら望遠やら自分の狙う撮影にあったレンズを付けてシャッターを押しフィルムに撮影します。
(3)ビューポート行列は座標系を合わせるのに使うだけです。 射影変換後は画一の単位なので640x480やら1280x780やらスクリーンの座標系に変換します。
撮影したフィルムを印画紙に焼きます。印画紙のサイズは色々あります。
(1)ビュー行列は、要するにカメラの前に世界を回して並べる行為です。イメージ的にはカメラを動かすと言ったほうが良いでしょうね。
すきなアングルで一眼レフカメラを構えます。
(2)射影行列は、カメラのレンズのようなものです。透視投影して2D座標系に変換を行います。世界→カメラレンズ→フォルムですね。
広角やら望遠やら自分の狙う撮影にあったレンズを付けてシャッターを押しフィルムに撮影します。
(3)ビューポート行列は座標系を合わせるのに使うだけです。 射影変換後は画一の単位なので640x480やら1280x780やらスクリーンの座標系に変換します。
撮影したフィルムを印画紙に焼きます。印画紙のサイズは色々あります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 3Dにおける角度の表現について
>>h2so5さん
私の場合は、MGetRotX,MGetRotY,MGetRotZの使い方を知らずに、いままで
行列をソースコードに埋め込んで、自前で計算していました。
こんな便利な関数があったんですね。
計算が私にとって、難しかったということです。
オイラー角は理解できます。言葉足らずでした。
DXライブラリには用意されていないけれど、DirectXAPIには
用意されているんですね。さすがです。
にたどりついたので、DXライブラリなしでも3Dプログラムを組めるのかな?
と思ってましたが、私には力不足です。
ビュー行列とか知らなくても3Dプログラミングは一応できるということなので、
できる範囲でいろいろやってみます。
回答ありがとうございました。
>>softya(ソフト屋)さん
私にはまだ、ジンバルロックが起きる条件などがはっきりしていないので、
また、じっくり本を読ませてもらいます。
雰囲気はわかったので、あとはいろいろ試します。
そうなのですね。h2so5さん さんが書きました:しかしながら、オイラー角や四元数による角度の表現から行列に変換することは可能です。
ですから最終的に行列になっていれば良いというだけです。
DXライブラリに行列を使った関数しか存在しないというのは間違いです。
DXライブラリの関数は基本的に「オイラー角」で角度を指定しています。
例えば、MGetRotXはオイラー角から行列に変換するための関数です。
MV1SetRotationXYZでは内部的にオイラー角が行列に変換されています。
MGetRotX
MGetRotY
MGetRotZ
MGetRotAxis
MGetRotVec2
MV1SetRotationXYZ
私の場合は、MGetRotX,MGetRotY,MGetRotZの使い方を知らずに、いままで
行列をソースコードに埋め込んで、自前で計算していました。
こんな便利な関数があったんですね。
1は理解できるが、2は理解できないというのは、h2so5さん さんが書きました: 「実例で学ぶゲーム3D数学」に書かれているとおり、行列による回転は人間にとっては直感的ではありません。
オイラー角のほうが分かりやすいはずなので、1は理解できるのに2が理解出来ないというのはちょっとおかしな話です。
DXライブラリの角度指定はオイラー角なのでそれを知っていればいいことになります。
計算が私にとって、難しかったということです。
オイラー角は理解できます。言葉足らずでした。
四元関数の線形補間というのは、まだ理解できていない範囲ですが、h2so5さん さんが書きました: 四元数は角度の線形補間を行いたい場合に便利ですがあまり直感的ではありません。
DXライブラリにはないかもしれませんが、DirectXにはAPIが用意されています。
DXライブラリには用意されていないけれど、DirectXAPIには
用意されているんですね。さすがです。
はい。本のリンクや、言葉などをたどっていくと、3Dグラフィクプログラミングh2so5さん さんが書きました: ビュー行列とか四元数とかの知識はDXライブラリを使っている以上はあまり重要ではありません。
知らなくてもいちおう3Dプログラミングはできます。
「実例で学ぶゲーム3D数学」の内容を理解していればDXライブラリなしでも3Dプログラミングできますが、
いまそれを目標にしなくても良いと思います。
にたどりついたので、DXライブラリなしでも3Dプログラムを組めるのかな?
と思ってましたが、私には力不足です。
ビュー行列とか知らなくても3Dプログラミングは一応できるということなので、
できる範囲でいろいろやってみます。
回答ありがとうございました。
>>softya(ソフト屋)さん
クォータニオンは必要に応じてですね。softya(ソフト屋)さん さんが書きました: DirectX9にはありますよ。
「その10 クォータニオンを学んでみよう!」
http://marupeke296.com/DXG_No10_Quaternion.html
まぁ、クォータニオンは自分で作れるので必要なら実装すれば良いだけです。
4元数を使わないと解決できないカメラなどの動きも有るので、必要に応じてという感じでしょうか。
ジンバルロックを防ぐ必要がある場合に使います。
私にはまだ、ジンバルロックが起きる条件などがはっきりしていないので、
また、じっくり本を読ませてもらいます。
わかりやすいたとえをありがとうございます。softya(ソフト屋)さん さんが書きました: 例えを思いついたので書いておきます。
(1)ビュー行列は、要するにカメラの前に世界を回して並べる行為です。イメージ的にはカメラを動かすと言ったほうが良いでしょうね。
すきなアングルで一眼レフカメラを構えます。
(2)射影行列は、カメラのレンズのようなものです。透視投影して2D座標系に変換を行います。世界→カメラレンズ→フォルムですね。
広角やら望遠やら自分の狙う撮影にあったレンズを付けてシャッターを押しフィルムに撮影します。
(3)ビューポート行列は座標系を合わせるのに使うだけです。 射影変換後は画一の単位なので640x480やら1280x780やらスクリーンの座標系に変換します。
撮影したフィルムを印画紙に焼きます。印画紙のサイズは色々あります。
雰囲気はわかったので、あとはいろいろ試します。
こちらこそ、複雑な3Dプログラムの質問に答えていただき、ありがとうございます。softya(ソフト屋)さん さんが書きました: 色々本やAPIなどで用語が違ったりするので間違っていたらごめんなさい。