2016-10-23 23 views
1

私は、その重心と座標系の中心(反時計回り)の周りを時計回りに回転させたい三角形を持っています。問題は、両方の動きが反時計回りであり、解決策を理解できないということです。三角回転のOpenGLシーケンス

from OpenGL.GL import * 
from OpenGL.GLUT import * 
from OpenGL.GLU import * 


def init(): 
    glClearColor(0.0, 0.0, 0.0, 0.0) 
    glClearDepth(1.0) 
    glMatrixMode(GL_PROJECTION) 
    glLoadIdentity() 
    gluOrtho2D(0.0, 640.0, 0.0, 480.0) 

rotation = 1 


def display(): 
    global rotation 

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) 
    glLoadIdentity() 

    glMatrixMode(GL_MODELVIEW) 
    glPushMatrix() 
    glRotate(rotation, 0.0, 0.0, 0.1) 
    glTranslatef(0.0, 0.0, -0.1) 
    glTranslatef(0.17, 0.17, 0.0) 
    glRotate(rotation, 0.0, 0.0, 0.1) 
    glTranslatef(-0.17, -0.17, 0.0) 
    glBegin(GL_TRIANGLES) 
    glColor3f(0.5, 0.5, 0.9) 
    glVertex3f(0.5, 0.0, 0.0) 
    glVertex3f(0.0, 0.5, 0.0) 
    glVertex3f(0.0, 0.0, 0.0) 
    glEnd() 
    glPopMatrix() 

    rotation += 1 
    if rotation >= 360: 
     rotation = 0 
    glFlush() 


if __name__ == '__main__': 
    glutInit() 
    glutCreateWindow('Rotating triangles') 
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH) 
    glutInitWindowSize(640, 480) 
    glutDisplayFunc(display) 
    glutIdleFunc(display) 
    init() 
    glutMainLoop() 

答えて

2

OpenGLの変換スタックについて理解するために重要なことは、その順序です。 OpenGLにおける変換行列の乗算の順番を考えると、変換コマンドはの逆で実行されます!

  1. 重心が世界の中心にくるようにオブジェクトを移動すると、私はあなたが要求した変換を実行する方法について考えています。
  2. 世界の中心を中心にして、オブジェクトを所望の速度で回転させます(これは、#1のために質量中心に相当します)。
  3. #1の逆変換を実行します。
  4. 追加の変換を実行して、オブジェクトの位置を希望するワールド位置に変更します(質問の場合はOPTIONAL)。
  5. 世界の中心を中心にして目的の速度でオブジェクトを回転させます(!=質量の重心)。あなたのコードにそれらの関連する変更を行うことに加え

、私は次のようでした:それは基本的に無限のwhileループだったもので、CPUに課税されませんので

  • は(フレーム間のプリミティブの遅延を追加しましたタスクマネージャとの違いを確認してください)。
  • glPushMatrixglPopMatrixの呼び出しを削除しました。ここでは、1つのオブジェクトだけを扱っているので、それらは不要です。通常は、プッシュしてからオブジェクトの変換を行い、ポップして各オブジェクトのプロセスを繰り返します。
  • モジュロ演算子を使用したif文の置き換え(正と負の回転を1行で処理)。
  • gluOrthoを呼び出しました。使用していた座標は、すべて-1と1の間でありました(デフォルトの投影法)。ここで

以下の変更されたコードは、いくつかの有益なコメントで、次のとおりです。

from OpenGL.GL import * 
from OpenGL.GLUT import * 
from OpenGL.GLU import * 
import time 


def init(): 
    glClearColor(0.0, 0.0, 0.0, 0.0) 
    glClearDepth(1.0) 
    glMatrixMode(GL_PROJECTION) 
    glLoadIdentity() 
    #commented gluOrtho2D out since its inclusion would require different vertex coordinates (i.e. not between -1 and 1) 
    #gluOrtho2D(0.0, 640.0, 0.0, 480.0) 


obj_rot = 0.0 
world_rot = 0.0 
obj_rot_speed = 5.0 
world_rot_speed = -1.0 

def display(): 
    global obj_rot 
    global world_rot 
    global obj_rot_speed 
    global world_rot_speed 

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) 
    glMatrixMode(GL_MODELVIEW) 
    glLoadIdentity()#not needed here, but good practice to reset state! 

    glRotate(world_rot, 0.0, 0.0, 1.0)#this transformation is peformed last (STEP 5) 
    glTranslatef(0.3, 0.3, 0.0)#OPTIONAL (GLOBAL) TRANSLATION OF THE TRIANGLE 
    glTranslatef(0.17, 0.17, 0.0) 
    glRotate(obj_rot, 0.0, 0.0, 1.0) 
    glTranslatef(-0.17, -0.17, 0.0)#this transformation is performed first (STEP 1) 

    glBegin(GL_TRIANGLES) 
    glColor3f(0.5, 0.5, 0.9) 
    glVertex3f(0.5, 0.0, 0.0) 
    glVertex3f(0.0, 0.5, 0.0) 
    glVertex3f(0.0, 0.0, 0.0) 
    glEnd() 

    obj_rot += obj_rot_speed 
    world_rot += world_rot_speed 
    obj_rot %= 360#simpler approach than if statement, which did not address negative rotation 
    world_rot %= 360 

    glFlush() 
    time.sleep(1/60.0)#VERY simplistically run the app at ~60 fps, avoids high CPU usage! 

if __name__ == '__main__': 
    glutInit() 
    glutCreateWindow('Rotating triangles') 
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH) 
    glutInitWindowSize(640, 480) 
    glutDisplayFunc(display) 
    glutIdleFunc(display) 
    init() 
    glutMainLoop() 

は、このいずれかが不明確である場合、私に教えてください!