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

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

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

GLFWは、OpenGLを使用してアプリ開発を行うためのフレームワークです。Macにも対応しているマルチプラットフォームであることが特徴。ウィンドウ管理、解像度切り替え、入力管理などの機能を持ちます。

OpenGL

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

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

2111閲覧

glRotated()関数を使って中心を中心に楕円を回転させる方法が知りたい。

退会済みユーザー

退会済みユーザー

総合スコア0

GLFW

GLFWは、OpenGLを使用してアプリ開発を行うためのフレームワークです。Macにも対応しているマルチプラットフォームであることが特徴。ウィンドウ管理、解像度切り替え、入力管理などの機能を持ちます。

OpenGL

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

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2021/06/23 01:19

提示コードですが回転しない場合は原点が中心なのですがglRotated()関数を使って回転させると中心を中心に回転してくれませんglVertex2f();にはどういった式を入れるべきなのでしょうか?

イメージ説明
イメージ説明

cpp

1 2 // ##################################### 楕円 描画 ##################################### 3 void DrawEllipse(glm::vec2 pos,int num, glm::vec2 size,float r, glm::vec4 color) 4 { 5 float dx = 1.0f / (FrameWork::getWindowContext()->getSize().x / 2); 6 float dy = 1.0f / (FrameWork::getWindowContext()->getSize().y / 2); 7 float c = 1.0f / 255.0f; 8 glColor4f(color.x * c, color.y * c, color.z * c, color.w * c); //カラー 9 10 pos.x = (pos.x * dx) - 1.0f; 11 pos.y = 1.0f - (pos.y * dy); 12 13 14 //glMatrixMode(GL_MODELVIEW); 15 16 glPushMatrix(); 17 glRotated(r,0,0,1); 18 19 glBegin(GL_TRIANGLE_FAN); 20 21 float f = (PI * 2) / num; 22 float ff = 0; 23 for (int i = 0; i < num; i++) 24 { 25 float x = cos(ff) * (size.x * dx); 26 float y = sin(ff) * (size.y * dy); 27 28 glVertex2f(pos.x + x, pos.y + y); 29 30 ff += f; 31 } 32 33 glEnd(); 34 glFinish(); 35 36 glPopMatrix(); 37 38 } 39 40

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

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

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

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

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

guest

回答1

0

ベストアンサー

座標 v に変換行列 R, T を乗じる場合に,乗じる順序によって結果が違う,という点は大丈夫ですかね.

R * T * v

T * R * v
とでは結果が違うのね.

R が「原点(0,0)まわりに回転させる」作用を持つ物ならば,
R * x として R を乗じる対象の x というのは,「回転中心にしたい場所を(0,0)とした座標系での値」にしないと所望の回転はできないわけ.

上の2つのパターンに括弧をつけてこの観点でわかりやすくかけば

  • R * ( T * v ) // R を乗じる対象は T * v
  • T * ( R * ( v ) ) // R を乗じる対象は v

となる.


さて,提示されたコードがどっち側かというと,前者の側になってるわけ.

glRotated(r,0,0,1); //←これがR.以降の物にRを乗じる
...
glVertex2f(pos.x + x, pos.y + y); //←これが T*v に相当.

つまり,
「(x,y)をposだけ並進させた結果」を回転させているわけね.

ここで,(x,y)というのが楕円の中心を(0,0)とした世界で考えている値なのであれば,
(x,y)という値が「回転中心にしたい場所を(0,0)とした座標系での値」なわけだ.
それをposだけ並進させてしまったら,その結果は「回転中心にしたい場所を(0,0)とした座標系での値」ではなくなってしまうよね.

だから,所望の回転とは異なった回転になるわけ.


以上より,
後者側の式になるようにコードを変更すれば良さそうだよね.
とりあえず

glRotated(r,0,0,1); //←これがR.以降の物にRを乗じる ... glVertex2f( x, y ); //←並進を除去して(x,y)とする

と書けば,
R * (x,y)
になるから,回転中心が所望の場所になる.

で,その回転させた結果を並進させればよいのだから,glTranslatedとかを使って

glTranslated( pos.x, pos.y, 0 ); //←これがT.以降の物にTを乗じる glRotated(r,0,0,1); //←これがR.以降の物にRを乗じる ... glVertex2f( x, y );

として,並進が回転よりも後に行われる形にすればいいんじゃないかな.


glTranslated( pos.x, pos.y, 0 ); {//このブロックの中の物を並進させるよ glRotated(r,0,0,1); {//このブロックの中の物を回転させるよ ... glVertex2f( x, y ); } }

とか書けば,見た目にわかりやすい形になるかもね.
(ブロックまで作らずともインデントするとかでも)

投稿2021/06/23 01:53

編集2021/06/23 02:03
fana

総合スコア11658

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

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

退会済みユーザー

退会済みユーザー

2021/06/23 02:01

まずは原点を中心に楕円を描いてそれの座標をpos分移動するということですね?
fana

2021/06/23 02:06

そうね.順序が大切. で,OpenGL で glRotated とかを書いた場所によってその順序がどうなるのか?というのを把握すべし. 回答末尾に追記したけど,それを視覚的に把握しやすいコードにしても良いと思う.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問