Rotating an object around a fixed point in opengl - opengl

I have a problem with this openGL code:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix(); // put current matrix on stack
//glTranslatef(0.0f, 0.0f, 0.0f);
//glTranslatef(-4*1.5, 0.0, 4*1.5);
glRotatef(rotationAngle, 0.0f, 1.0f, 0.0f); // rotate the robot on its y-axis
glTranslatef(xpos, ypos, zpos);
DrawRobot(xpos, ypos, zpos); // draw the robot
glPopMatrix();
What should I do to make my robot turn around the point at which it is currently situated and not around the origin? I think the problem lies in this snippet.

Example of rotating an object around its centre along the z-axis:
glPushMatrix();
glTranslatef(250,250,0.0); // 3. Translate to the object's position.
glRotatef(angle,0.0,0.0,1.0); // 2. Rotate the object.
glTranslatef(-250,-250,0.0); // 1. Translate to the origin.
// Draw the object
glPopMatrix();

Simply do the rotation after the translation. The order matters.
glTranslatef(xpos, ypos, zpos);
glRotatef(rotationAngle, 0.0f, 1.0f, 0.0f);

try rotating after translation:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix(); // put current matrix on stack
//glTranslatef(0.0f, 0.0f, 0.0f);
//glTranslatef(-4*1.5, 0.0, 4*1.5);
glTranslatef(xpos, ypos, zpos);
glRotatef(rotationAngle, 0.0f, 1.0f, 0.0f); // rotate the robot on its y-axis
DrawRobot(xpos, ypos, zpos); // draw the robot
glPopMatrix();

Use this
house();
glTranslatef(x, y, 0.0); // 3. Translate back to original
glRotatef(theta, 0.0, 0.0, 1.0); // 2. Rotate the object around angle
glTranslatef(-m, -n, 0.0); // 1. Move to origin
house();
where m and n are the point on the object around which you want to rotate and
x and y are the points around which you want to rotate.

Related

Changing the rotation point along with object moving in OpenGL?

I'm trying to build a hammer weapon that can move along with the X-axis and rotate around Z-axis. Right now I have a problem with the hammer. The hammer can rotate around Z-axis on a fixed pivot point, but when I move the hammer to a new position then I rotate the hammer, the hammer still rotates around the old pivot point.
I have tried to add the distance I moved to the old pivot point, but it does not work. How could I solve this problem? Thanks for any helping!
Here is my code:
glPushMatrix();
//the rotation angle of Z-axis
glTranslatef(0.5f,1.0f,-1.0f); //Back to original point
glRotatef(zr, 0.0f, 0.0f, 1.0f); //Rotating
glTranslatef(-0.5f,-1.0f,1.0f); //The rotation piovt point
//build weapon base
//the moving distant on X-axis
glPushMatrix();
glColor3f(1, 0, 0);
glTranslatef(0.5f+xr, 1.0f, -1.0f);
glRotatef(-90.0, 1.0, 0.0, 0.0);
quadratic = gluNewQuadric();
gluCylinder(quadratic, 0.2f, 0.2f, 2.0f, 50, 50);
glPopMatrix();
//build hammer
glPushMatrix();
glTranslatef(0.0+xr, 3.0f, -1.0f);
glRotatef(90.0, 0.0, 1.0, 0.0);
glColor3f(0, 1, 0);
quadratic = gluNewQuadric();
gluCylinder(quadratic, 0.2f, 0.2f, 1.0f, 50, 50);
glPopMatrix();
glPopMatrix();
You have to move the pivot, too:
float pivot_x = 0.5f + xr;
glTranslatef(pivot_x, 1.0f, -1.0f); //Back to original point
glRotatef(zr, 0.0f, 0.0f, 1.0f); //Rotating
glTranslatef(-pivot_x, -1.0f, 1.0f); //The rotation piovt point

OpenGL translation before and after a rotation

The following is code (taken from http://www.glprogramming.com/red/chapter03.html) regarding how to draw a robot's arm and shoulder and rotating them by some user input:
glPushMatrix();
glTranslatef (-1.0, 0.0, 0.0);
glRotatef ((GLfloat) shoulder, 0.0, 0.0, 1.0);
glTranslatef (1.0, 0.0, 0.0);
glPushMatrix();
glScalef (2.0, 0.4, 1.0);
glutWireCube (1.0);
glPopMatrix();
glTranslatef (1.0, 0.0, 0.0);
glRotatef ((GLfloat) elbow, 0.0, 0.0, 1.0);
glTranslatef (1.0, 0.0, 0.0);
glPushMatrix();
glScalef (2.0, 0.4, 1.0);
glutWireCube (1.0);
glPopMatrix();
glPopMatrix();
glutSwapBuffers();
I understand the code for drawing the shoulder and rotating it. For the shoulder: first we translate it one unit back along the x-axis so that when we do the rotation, it rotates along the origin as a pivot. Then we translate it back (forward one unit on the x-axis). This transformation will be applied to the cube that has been scaled.
Now, my question is for the elbow. Why is there a translation forward on the x-axis both before and after the rotate?
Now, my question is for the elbow. Why is there a translation forward on the x-axis both before and after the rotate?
If you want to imagine how the matrix operations change the model, then you need to "read" the operations in the reverse order.
This is, because the current matrix of the matrix stack is multiplied by the matrix which is specified by the new operation and the matrices are stored in column-major order (fixed function pipeline).
Start with the elbow cube
glutWireCube(1.0f);
Scale the elbow
glPushMatrix();
glScalef(2.0f, 0.4f, 1.0f);
glutWireCube(1.0f);
glPopMatrix();
Move it to the right
glTranslatef(1.0f, 0.0f, 0.0f);
Rotate the elbow
glRotatef(45.0f, 0.0f, 0.0f, 1.0f);
Move the rotated elbow to the right
glTranslatef(1.0f, 0.0f, 0.0f);
Draw the shoulder cube
glutWireCube(1.0f);
Scale the shoulder
glPushMatrix();
glScalef(2.0f, 0.4f, 1.0f);
glutWireCube(1.0f);
glPopMatrix();
Move the arm (elbow and shoulder) to the right
glTranslatef(1.0f, 0.0f, 0.0f);
Rotate the arm
glRotatef(-15.0f, 0.0f, 0.0f, 1.0f);
Move the arm to its final position (to the left)
glTranslatef(-1.0f, 0.0f, 0.0f);

OpenGL renders nothing after using gluLookAt

This is my source If I build this source without the function I can see only 2 lines. But I want to see the 'z'axis.
So I added the gluLookAt() function but I can see just black screen.
What's wrong with my code? Is the camera's point of view is wrong?
It is created on the MFC dialog box. Please help me.
void CopglDlg::OnTimer(UINT_PTR nIDEvent)
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
gluLookAt(3.f, 3.f, 3.f, 0.f, 0.f, 0.f, 0.f, 0.f, 1.f);
glBegin(GL_LINE_LOOP);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(1.0, 0.0, 0.0);
glVertex3f(-1.0, 0.0, 0.0);
glEnd();
glBegin(GL_LINE_LOOP);
glColor3f(0.0, 1.0, 0.0);
glVertex3f(0.0, 1.0, 0.0);
glVertex3f(0.0, -1.0, 0.0);
glEnd();
glBegin(GL_LINE_LOOP);
glColor3f(0.0, 0.0, 1.0);
glVertex3f(0.0, 0.0, 1.0);
glVertex3f(0.0, 0.0, -1.0);
glEnd();
glFlush();
When in OpenGL a vertex (point) is processed, it gets transformed by the modelview matrix and the projection matrix.
The projection matrix describes the mapping from 3D points of a scene, to 2D points of the viewport. The projection matrix transforms from view space to the clip space, and the coordinates in the clip space are transformed to the normalized device coordinates (NDC) in the range (-1, -1, -1) to (1, 1, 1) by dividing with the w component of the clip coordinates. All the geometry which is out of the clip space is clipped and unvisible.
The modelview matrix is a combination of the model matrix and the view matrix.
The view matrix describes the direction and position from which the scene is looked at. The view matrix transforms from the wolrd space to the view (eye) space.
The model matrix defines the location, oriantation and the relative size of a mesh in the scene.
In OpenGL all matrix operations, are applied to the matrix stack you have specified by glMatrixMode.
In your case you did not set up a projection matrix, so the projection matrix is by default the identity matrix. This means the far plane is by default at 1 and every thing what is farer away from your eye position (3.0, 3.0, 3.0) than 1, gets clipped by the far plane and is not visible.
You can either change the view matrix, so that you can see out from the center (Note, if the projection matrix is the identity matrix, then the projection is an orthographic projection, the near plane is at -1 and the far plane at +1, so the area around the eye position is in the clip space):
glMatrixMode(GL_MODELVIEW);
gluLookAt(0.0f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 1.0f);
Or you set up a projection matrix with a far plane, that is far enough away to include the area where your lines are in (see glOrtho):
glMatrixMode(GL_PROJECTION);
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 10.0 );
glMatrixMode(GL_MODELVIEW);
gluLookAt(3.0f, 3.0f, 3.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
OpenGL only shows you what is inside an unitary cube. Once you moved your camera 3 steps on each direction, your lines does not fit inside this new cube.
In order to see it, I sugest to move your camera near your orign point:
gluLookAt(.5f, .5f, .5f, 0.f, 0.f, 0.f, 0.f, 0.f, 1.f);
Or create a new visualization volume, by stablishing an orthographic projection

Why does this OpenGL rotation also translate my object?

I'm trying to rotate an object (an arrow) which has it's default position as pointing to the right. I've been looking around and I'm using the glLoadIdentity() and glPushMatrix() and glPopMatrix() as a way to only rotate the object in my glBegin function and not the whole scene:
glLoadIdentity();
glPushMatrix();
glRotatef(5, 0.0f, 0.0f, 1.0f);
glBegin(GL_TRIANGLE_FAN);
glColor3f(1.0f, 0.0f, 1.0f);
glVertex2f(xx2-0.01, yy2);
glVertex2f(xx2-0.06, yy2+0.03);
glVertex2f(xx2-0.06, yy2-0.03);
glEnd();
glPopMatrix();
However, it also translates my arrow, instead of only rotating it. Do I need to translate the offset back to it's original position? Or am I doing something wrong?
SOLVED:
glLoadIdentity();
glPushMatrix();
glTranslatef(xx2, yy2, 0);
glRotatef(45, 0.0f, 0.0f, 1.0f);
glTranslatef(-xx2, -yy2, 0);
glBegin(GL_TRIANGLE_FAN);
glColor3f(1.0f, 0.0f, 1.0f);
glVertex2f(xx2-0.01, yy2);
glVertex2f(xx2-0.06, yy2+0.03);
glVertex2f(xx2-0.06, yy2-0.03);
glEnd();
glPopMatrix();
Need to translate back to center (0, 0, 0), apply the rotation and then back to it's original position (xx2, yy2, 0)
All rotations are around the origin.
So yes, if you want to rotate around some other point, you must translate from that point to the origin, rotate, and then translate back again.
Your code is correct, but you are applying your operations out of order. Specifically, you need to apply the rotation first, then apply the translation.

How to draw cylinder in y or x axis in opengl

I just want to draw a cylinder in opengl. I found lots of samples but all of them draws cylinders in z axis. I want them be in x or y axis. How can i do this. The code below is the code draw the cylinder in z direction and i dont want it
GLUquadricObj *quadratic;
quadratic = gluNewQuadric();
gluCylinder(quadratic,0.1f,0.1f,3.0f,32,32);
You can use glRotate(angle, x, y, z) to rotate your coordinate system:
GLUquadricObj *quadratic;
quadratic = gluNewQuadric();
glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
gluCylinder(quadratic,0.1f,0.1f,3.0f,32,32);
http://www.opengl.org/sdk/docs/man/xhtml/glRotate.xml
On every render use glPushMatrix glRotatef draw the cylinder and finish your drawing with glPopMatrix.
Ex.: glRotatef(yRotationAngle, 0.0f, 1.0f, 0.0f); // Rotate your object around the y axis on yRotationAngle radians
Ex.: OnRender() function example
void OnRender() {
glClearColor(1.0f, 0.0f, 0.0f, 1.0f); // Clear the background
glClear(GL_COLOR_BUFFER_BIT); //Clear the colour buffer
glLoadIdentity(); // Load the Identity Matrix to reset our drawing locations
glRotatef(yRotationAngle, 0.0f, 1.0f, 0.0f); // Rotate our object around the y axis on yRotationAngle radians
// here *render* your cylinder (create and delete it in the other place. Not while rendering)
gluCylinder(quadratic,0.1f,0.1f,3.0f,32,32);
glFlush(); // Flush the OpenGL buffers to the window
}