PDA

View Full Version : Rotating an object

Amit5
10-25-2009, 12:15 PM
Hey,

I'm using glut and I'm trying to rotate an object around a given vertex and for some reason the rotation radius is huge.
here's the code:

int x=180,y=200,angle=45;

glPushMatrix();
glTranslatef(x,y,0);
glRotatef(angle,0,0,1);

glLineWidth(10);
glBegin(GL_LINES);
glColor3f(0.2f,0.2f,1.0f);
glVertex2f(200,200);
glVertex2f(205,200);
glColor3f(0.9f,0.9f,0.9f);
glVertex2f(205,200);
glVertex2f(215,200);
glColor3f(0.8f,0.42f,0.2f);
glVertex2f(215,200);
glVertex2f(255,200);
glEnd();
glPopMatrix();

can anyone help?

marshats
10-25-2009, 01:39 PM
Your question is incomplete. What matrix stack does your glLoadIdentity apply to: glMatrixMode(GL_MODELVIEW) or glMatrixMode(GL.GL_PROJECTION)? You should be working on the GL_MODELVIEW stack.

Since your glVertex2f 2nd argument is always 200, Your code is drawing a line centered at approximately (228,200). Is that what you meant to do?

Second, when you apply rotations/translations/scale/etc it is convenient to think of the order of operations in global coordinates in reverse order as the code. By this I mean in your case reading the code from glBegin _UP_. Your code directly means that you first apply a rotation then apply a translation second. You are applying a rotation of 45 degrees about the origin (0,0) with the line centered at (228,200) -- this is why your radius appears to be so large.

I suggest taking the time to read the Redbook Chapter 3 (http://glprogramming.com/red/chapter03.html).

Here is a quick code to show how to rotate around a particular vertex point (x=215, y=200). Note the beginning fast roation for ~1 second is due to a timer calibrating to a fixed FPS

#include <cstdlib>
#include <iostream>

//linux openGL headers (replace with appropriate OS one here if needed)
#include <GL/gl.h>
#include <GL/glut.h>

GLint gFramesPerSecond = 0;
GLfloat gAngle = 0.0;

void FPS(void) {
static GLint Frames = 0; // frames averaged over 1000mS
static GLuint Clock; // [milliSeconds]
static GLuint NextClock = 0; // [milliSeconds]

++Frames;
Clock = glutGet(GLUT_ELAPSED_TIME); //has limited resolution, so average over 1000mS
if ( Clock < NextClock ) return;

gFramesPerSecond = Frames/1; // store the averaged number of frames per second

NextClock = Clock+1000; // 1000mS=1S in the future
Frames=0;
}

void timer(int value)
{
const int desiredFPS=120;
glutTimerFunc(1000/desiredFPS, timer, ++value);
GLfloat dt = (gFramesPerSecond>0 ? 1.0/gFramesPerSecond : 1.0);

//put your specific idle code here
//... this code will run at desiredFPS
gAngle += dt*360./8.; //rotate 360 degrees every 8 seconds
//end your specific idle code here

FPS(); //only call once per frame loop to measure FPS
glutPostRedisplay(); // initiate display() call at desiredFPS rate
}

void display() {
// Will be called at FPS rate, ok to use global values now to rener scene
glClear(GL_COLOR_BUFFER_BIT);

//quick and dirty way to display FPS value
printf("FPS %d\r",gFramesPerSecond); fflush(stdout);

glColor3f(1.0,1.0,1.0);

glMatrixMode(GL_MODELVIEW);

GLfloat x=215, y=200;

glPushMatrix();
glTranslatef(x,y,0); // 3rd move rotated line back to original location
glRotatef(gAngle,0.,0.,1.); // second rotate line about origin
glTranslatef(-x,-y,0); // first translate line to origin

glBegin(GL_LINES);
glColor3f(0.2f,0.2f,1.0f);
glVertex2f(200,200);
glVertex2f(205,200);
glColor3f(0.9f,0.9f,0.9f);
glVertex2f(205,200);
glVertex2f(215,200);
glColor3f(0.8f,0.42f,0.2f);
glVertex2f(215,200);
glVertex2f(255,200);
glEnd();
glPopMatrix();

glutSwapBuffers();
}

void init() {
glClearColor(0.0, 0.0, 0.0, 0.0);

glMatrixMode(GL_PROJECTION);
glOrtho(-300.0,300.0,-300.0,300.0,-1.0,1.0);
}

void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27: // escape key
exit(0);
break;
default:
break;
}
}

int main(int argc, char** argv) {
glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_DOUBLE);
glutCreateWindow("FPS test /w glutTimerFunc");

glutTimerFunc(0,timer,0);
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);

init();

glutMainLoop();
return 0;
}