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

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

新規登録して質問してみよう
ただいま回答率
85.35%
OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

Q&A

解決済

1回答

2854閲覧

opengl 拡大、縮小 回転 並進の手順についておよび glScaledの抹消について。

txty

総合スコア303

OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

0グッド

0クリップ

投稿2020/08/05 16:04

編集2022/07/26 12:38

質問が2つほどあるのですが、

ちょっと思いついちゃったんですけど、この間聞けば良かった。

opengl

1質問1 2「1」.計算の語順ですが以下のように、拡大縮小、回転、並進。 3 4「2」.回転、拡大縮小、並進。はどちらがただしいのでしょうか。 5 6

「1」と「2」はどちらがただしいのでしょうか。

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

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

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

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

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

guest

回答1

0

ベストアンサー

「1」と「2」はどちらがただしいのでしょうか

それを他者に問うても解はありません.
各変換をどのような順で適用していくべきか,というのは,あなたが何を計算しているのかに完全に依存する話であるからです.


あなたが行おうとしている

拡大縮小、回転、並進

なる複数の変換(を合成した変換)に関して,

  • 変換を適用する前のデータ(座標)値を記述している座標系
  • 変換を適用した後のデータ(座標)値を記述している座標系

があってその間での座標変換を行う話であるならば,両者の間の座標変換の式を立てる(しっかり定める)ことから始めるべきです.
つまり,あなたが「計算手順の仕様」を決めて,その通りの計算を実装する話です.

もちろん,{拡大縮小,回転,並進}なる変換群をどのような順序で適用していくか次第で,個々の変換の「考えやすさ」が変わりますから,ご自身がやりたい話の上で「各変換を考えやすい」仕様にするとよいでしょう.

e.g.
1次元で考えればわかりやすいかな.

  • 「2倍に拡大してから,10だけ並進させる」 : x' = 2x + 10
  • 「10だけ並進させてから,2倍に拡大する」 : x'' = (x + 10) * 2

の両者では,
与えている「2倍」とか「10だけ並進」とかいう「変換のための量」は同じであっても,結果が異なります.
つまり,ある狙いの結果を得るために与えるべき個々の変換のための量というのは,用いる式によって異なるということです.
「質問2」のスケールが上手くいかないとかいう話も,こういった話に起因するのかもしれません(何がどう上手くいかないのか不明なので断定できませんが).

投稿2020/08/06 01:34

編集2020/08/06 01:50
fana

総合スコア11996

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

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

txty

2022/07/26 12:40 編集

回答ありがとうございます。参考にして、しっかり考えます。
txty

2022/07/26 12:41 編集

削除。
fana

2020/08/07 04:49 編集

何を訊かれているのか,正直よくわかりませんが… あなたが書いているコードの「計算の順序」とは,そのコードに書いた順序そのものでしょう. (書いた順序と異なる計算がなされるとしたら,困るでしょう?) OpenGLの関数のイメージとしては,「glVertex3f(頂点座標) に近い順に,適用されていく」. 例えば,コードが, glLoadIdentity(); glTranslated( ... ); //並進 glScaled( ... ); //スケーリング glRotated( ... ); //回転 glvertex3d( 頂点座標 ); と書かれていたら, 「「(頂点座標)を回転した結果」をスケーリングした結果」を並進 ということになる. (つまり,"コードの見た目には" 関数呼び出しを書いた順序とは逆の順序で計算される)
fana

2020/08/07 04:54

OpenGLでは,座標変換が(4x4の)行列Mを用いて 「変換後座標 = M * 頂点座標」 となる. glLoadIdentity()は,Mを単位行列で初期化する. glTranslated()等の関数は, 「M = M * その関数による変換行列」 としてMを更新するものである.だから,前記のコード例でいえば,glLoadIdendity()~glRotated()までの関数呼び出しによって, M = I * T * S * R という形でMの内容が計算される.(Iは単位行列,T,S,Rはそれぞれの関数による変換行列) そしてこのMが頂点座標に掛けられるのだから,結果として 「変換後座標 = I * T * S * R * 頂点座標」ということになるわけだ. これは,わかりやすいように括弧を付けてみれば 「変換後座標 = I * (T * (S * (R * 頂点座標)))」 ということだ. > (つまり,"コードの見た目には" 関数呼び出しを書いた順序とは逆の順序で計算される) とは,そういうことだ.
txty

2022/06/13 00:32 編集

なぜI*T*S*Rになるんでしょうか。 また、glPushMatrix()~glPopMatrix()でくくってしまっているんですけどこれって順番に影響ないですよね?
fana

2020/08/07 10:04

> …という認識だけでもいいでしょうか いいかどうか(どこまでを知らずにいてよいか)はこちらが決めることではありませんが, 「行われている演算の意味を把握してから → その実装たるライブラリ関数なりを使う」というのが正当な(?)順序であろうと個人的には考えます. * 計算内容を把握していないと,例えば「マウスでドラッグしたら表示物をそのドラッグ方向に応じて回転させたい」といった "些細な応用" を行いたいときに,どこに何をどう書けばよいのかが全くわからないでしょう. 実際,OpenGLのようなものをある種のブラックボックスとして使う人がこのようなことで躓くのをわりとよく見てきました. * このコメント欄にて "行列M" と表記した「何か」の存在やその意味を把握していなければ,glPushMatrix()やglPopMatrix()を正常に扱うこともできないでしょう.
txty

2020/08/07 10:40 編集

すいません。行きちがいました。ライブラリのの一部だけをみると個人的にものたりないのと移植の際、楽になるかもという点から作ろうとしはじめてしまうことがあります。glPushMatrix(); glPopmatrix();はブロックコードにしか見えません。わかってないということですが。glPushMatrix()~glPopMatrix();でくくってない部分をみるとちんぷんかんぷんです。(1度)見ただけですけど。
fana

2020/08/07 10:49

まぁ,こんなところで私のような素人の話を聞くよりも(玄人は回答やコメントに来てくれない様子ですし),一度まともな解説なりをきちんと読むことをお勧めします. 階段を数段飛ばしで上ったら問題が生じるのであれば,数段飛ばしを行うべきではなかろうと思います. このジャンル(3D)というのは,特に最初の数段を飛ばさないことが重要なのではないかと思います.
txty

2022/05/31 10:45 編集

今までもっと勉強しとけばよかったなと思います。
fana

2020/08/07 13:33

(何故その他人の質問を推してくるのが謎ですが,知らない事は答えられませぬ.)
txty

2022/05/31 10:49 編集

他人を推してしまったので、削除
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問