Reputation: 8310
I have a triangle that I would like to rotate clockwise around its center of mass as well as the center of the coordinate system (counterclockwise). The problem is that both movements are counterclockwise and I can't figure out the solution.
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()
Upvotes: 1
Views: 528
Reputation: 2465
The key thing to understand about OpenGL's transformation stack is its order. Given the order of transformation matrix multiplication in OpenGL, the transformation commands are performed in reverse! Here is how I would think about performing the transformation that you had requested:
In addition to making those relevant changes to your code, I did the following:
glPushMatrix
and glPopMatrix
calls. They were unneeded here as you are only working with one object. You would typically push, then do an object transformation, then pop and repeat the process for each object.gluOrtho
call. The coordinates you were using were all between -1 and 1 (i.e. the default projection).Here is the modified code below, with some helpful comments:
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()
Let me know if any of this is unclear!
Upvotes: 2