Advertisement

Rotating an object around an arbitrary point?

Started by May 09, 2002 08:26 PM
7 comments, last by WhatEver 22 years, 9 months ago
Let''s say you have a ball that''s centered around 0,0,0. I want to rotate this ball around an arbitrary point in space...for this example let''s say 10,0,0. Right now I''m creating a transformation matrix that uses 10,0,0 and then I inverse that and then transform the balls physical vertices. When I do this the balls origin is no longer centered around 0,0,0, but 10,0,0, that way I can rotate the object then transform it by 10,0,0. I have a person model that I''m trying to animate. I don''t want each of the parts centered around their pivot points staticly...I want to leave the person model in the normal standing position and rotate each bone without having to transform each part to their local axis. Am I being clear? It''s so hard to explain. I know there has to be a way to not modify the original vertices to rotate the object...there has to be! So is there a way?
Actually I meant around an arbitrary 3 space 4x4 matrix(I guess that''s what you can call it).
Advertisement
Translate by the inverse of the point you want to rotate about, perform the rotation, and translate back.

To rotate by 90 degrees about 2,2,2 around the y axis:

glPushMatrix ();
glTranslatef (-2,-2,-2);
glRotatef (90, 0, 1, 0);
glTranslatef (2,2,2);
//Do stuff
glPopMatrix ();
I''ll have to try that tomorrow. I tried something before that I thought should work...I just can''t remember what. It might have been what you just mentioned...I hope not .
quote:

To rotate by 90 degrees about 2,2,2 around the y axis:

glPushMatrix ();
glTranslatef (-2,-2,-2);
glRotatef (90, 0, 1, 0);
glTranslatef (2,2,2);
//Do stuff
glPopMatrix ();


Aren''t matrix operations in OpenGL is applied bottom up (as written in the code), last transformation applied to the matrix stack is the first to affect the vertex? Then that code will translate the point of rotation to (4,4,4), not (0,0,0), before the rotation. Think it should be like this.

  glPushMatrix ();glTranslatef (2,2,2);glRotatef (90, 0, 1, 0);glTranslatef (-2,-2,-2);/Do stuffglPopMatrix ();   
I am pretty sure that what you are looking for is a matrix stack. I think the tutorials in the help of DirectX were pretty helpful for this (you can find them on MSDN).

The idea is to create a hierarchy of body parts. Each level of the hierarchy represents a different coordinate system. For example, the fingers are part of the hand space, that is part of the arm space, that is part of the body space. First, you push the world matrix of the body onto the stack. Then, you duplicate that matrix, and multiply it by the matrix of the arm (in body space). Repeat for the hand and fingers.

I hope that was clear. Search with Googles if not.

Cédric
Advertisement
Thanx for the help guys. invective got me thinking about this while I was at work today. For some reason I figure this stuff out in my head better than if I were to expiriment with it in my source code.

invective is right. I did this way back when I was trying it:

glPushMatrix ();
glTranslatef (-2,-2,-2);
glTranslatef (2,2,2);
glRotatef (90, 0, 1, 0);
glPopMatrix ();

Duh huh.

Brother Bob, you can think of each matrix as a coordinate system in arbitrary world space(since that''s what they are ). The identity is the worlds origin. When you push a matrix you''re starting point starts relative to the last coordinate system(matrix) you pushed.

When you set up a rotation matrix, all you''re doing is generating a coordinate system based on your rotation info.

I hope that also made sense .
Here''s a simple GLUT program rotating a teapot about an arbitrary point in space.

  #include <GL/glut.h>double angleX = 0;double angleY = 0;void display(void){	glClear(GL_COLOR_BUFFER_BIT);	glLoadIdentity();	gluLookAt(0, 0, 5, 0, 0, 0, 0, 1, 0);	// Rotate the object about the point (2, 2, 1)	glTranslated(2, 2, 1);	glRotated(angleX, 1, 0, 0);	glRotated(angleY, 0, 1, 0);	glTranslated(-2, -2, -1);	// Draw a teapot at the origin	glColor3f(1, 0, 0);	glutWireTeapot(1);		// Draw a line from the origin to the point of rotation	glColor3f(0, 1, 0);	glBegin(GL_LINES);	glVertex3f(0, 0, 0);	glVertex3f(2, 2, 1);	glEnd();	glutSwapBuffers();}void reshape(int x, int y){	glViewport(0, 0, x, y);	glMatrixMode(GL_PROJECTION);	glLoadIdentity();	gluPerspective(80, 1, 0.1, 10);	glMatrixMode(GL_MODELVIEW);	glLoadIdentity();}void idle(void){	angleX += 1;	angleY += 2;	glutPostRedisplay();}void main(int argc, char **argv){	glutInit(&argc, argv);	glutInitDisplayMode(GLUT_DOUBLE);	glutCreateWindow("Foo");	glutDisplayFunc(display);	glutIdleFunc(idle);	glutReshapeFunc(reshape);	glutMainLoop();}  

Have a look in the display function. The point of rotation is (2, 2, 1), and notice the order of the translate commands. I also draw a line from the origin to the point of rotation, and you can see that the end of the line is fixed on the screen, since it''s located at the origin of the rotation, and therefore its position isn''t affected by the rotation. Change the order of translation, and the point of rotation is no longer at the end of the line.

This tells me, if you want to rotate about the point P, you must first (as written in the code) translate by P, rotate, and then translate by -P, and it confirms what I said.
Brother Bob, I tried your method and it worked perfectly. It makes sense now that I think of it. It seems backwards at first...but it worked perfectly.

Thx!

This topic is closed to new replies.

Advertisement