I want to rotate a gluSphere around a fixed point in a circular motion, like a planet going around the sun.
Would it be best to use glRotatef or glTranslate? If so, in which order should I call them?
You'll have to do a little of both:
Make sure the gluSphere is "facing" the fixed point, so that translating forward with respect to the sphere puts you closer to the center of its orbit
glTranslatef the gluSphere forward to the point around which you want it to rotate
glRotatef the direction you want the sphere to orbit
glTranslatef backwards just as far as you went forward
That way, your sphere stays the same distance from the center, but gets translated "around" in a nice orbit.
Translate away from the center and then rotate all the way
glRotatef will multiply the current matrix by a rotation matrix. This can (given the right vector) do what you are attempting.
glTranslatef will multiply the current matrix by a translation matrix, which would effectively "move" the object, not rotate it, so it will not be what you want.
Related
Can someone please advise how to rotate a triangle from its top vertice?
I want to make multiple triangles in a fan to make a circle with a common middle point, the top vertice of the triangle.
You can rotate around a point by first translating with its inverse coordinate to the origin, then rotate by your angle and translate back to the reference point.
If you want to draw a circle consider using a triangle fan instead.
I have a basic cube generated in my 3D world. I can rotate correctly around the camera, but when I translate after rotating, the translations are not correct.
For example, if I rotate 90 degrees and translate into the Z axis, it would move as if translating in the X axis.
glLoadIdentity();
glRotatef(angle,0,1,0); //Rotate around the camera.
glTranslatef(movX,movY,movZ); //Translate after rotating around the camera.
glCallList(cubes[0]);
I need some help with this. Also, I tried translating before rotating, but the rotation is not at the camera. It is at the edge of the cube.
Keep in mind that in OpenGL that the transformation is applied to the camera, not the objects rendered; so you observe the inverse of the transformation you expected.
Also in OpenGL the Y and Z axes are flipped (Y is vertical), so you observe a horizontal translation instead of a vertical one.
Also, because the object is rotated though 90 degrees about Y, the X and Z axes replace each other (one of them is reversed).
willywonkadailyblah's answer is half correct. Because you are using the old OpenGL, you're using the old matrix stack. You are modifying the modelview matrix when you're doing your glRotatef and glTranslatef calls. The modelview matrix is actually the model's matrix and the camera's view matrix precombined (already multiplied together). These matrices are what determine where your object is in 3D space and where your viewing position/direction of the world is. So you can think of your calls as moving the camera, but it's probably easier to think of them as moving and rotating the world.
These rotate and translation calls are linear transformations. This has a precise definition, but for our purposes it means that you can represent the transformation as a matrix and you multiply it with the point's coordinates to apply the transformation to a point. Now matrix multiplication is not commutative, meaning AB != BA. All this to say that when you rotate, then translate it is different than translating and rotating, which I think you know. But then when you translate, rotate, and translate again, it might be a little more difficult to follow what you're actually doing. Worse even if you throw in some scaling in there. So I would suggest learning how linear transformations work and maintaining your own matrices for the objects and camera if you're serious about learning OpenGL.
learnopengl.org is an excellent website, but it teaches you Modern OpenGL, not what you're currently using. But the lesson on transformations and on coordinate systems are probably generally helpful, even without exact code for you to follow
I understand that in OpenGL, we use the gluLookAt to place the camera relative to the world and thus define the image that would be drawn.
The "eye" specifies the position of the camera and the "center" specifies the point the camera is pointing towards. Once we know these two, we can draw a straight line from the eye to the center. The camera plane would be normal to this line.
Since we know this plane, the up vector specifies the top of the camera - basically which direction in this plane is upwards. Thus the up vector is always orthogonal to the vector joining the center and the eye.
My question is why do we need the full vector, when we just want to know the angle of rotation about the line joining "center" and "eye". Is the reason behind this a computational advantage that I am not aware of? And what if someone specifies a wrong up vector, which is not orthogonal to the direction of sight?
The up vector you pass in is used to indicate the up direction, but this is used with a cross product. I think the purpose of gluLookAt is to simplify the calculations needed by the user, so for example you would just pass (0,1,0) to indicate that the up direction you desire is along the positive Y-axis.
If you want better efficiency you could avoid gluLookAt entirely
I have an object right now which I have moving in a circle around the vertical (Y) axis. I want to rotate this object so it is always aligned with the tangent of the circle, how do I do this? Not sure what combination of sin/cosine/tan to use as the first argument of glRotatef...
Thanks!
The first argument of glRotatef is the angle, in radians (so 0 is no rotation, PI is flipped around end for end, and 2*PI is rotated all the way back to the original orientation).
You probably could have answered this yourself through trial and error in less time than it took to askk the question.
Note that if you choose the center of rotation to be the center of the circle instead of the center of the object, you won't need a separate translation step.
Using OpenGL I'm attempting to draw a primitive map of my campus.
Can anyone explain to me how panning, zooming and rotating is usually implemented?
For example, with panning and zooming, is that simply me adjusting my viewport? So I plot and draw all my lines that compose my map, and then as the user clicks and drags it adjusts my viewport?
For panning, does it shift the x/y values of my viewport and for zooming does it increase/decrease my viewport by some amount? What about for rotation?
For rotation, do I have to do affine transforms for each polyline that represents my campus map? Won't this be expensive to do on the fly on a decent sized map?
Or, is the viewport left the same and panning/zooming/rotation is done in some otherway?
For example, if you go to this link you'll see him describe panning and zooming exactly how I have above, by modifying the viewport.
Is this not correct?
They're achieved by applying a series of glTranslate, glRotate commands (that represent camera position and orientation) before drawing the scene. (technically, you're rotating the whole scene!)
There are utility functions like gluLookAt which sorta abstract some details about this.
To simplyify things, assume you have two vectors representing your camera: position and direction.
gluLookAt takes the position, destination, and up vector.
If you implement a vector class, destinaion = position + direction should give you a destination point.
Again to make things simple, you can assume the up vector to always be (0,1,0)
Then, before rendering anything in your scene, load the identity matrix and call gluLookAt
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt( source.x, source.y, source.z, destination.x, destination.y, destination.z, 0, 1, 0 );
Then start drawing your objects
You can let the user span by changing the position slightly to the right or to the left. Rotation is a bit more complicated as you have to rotate the direction vector. Assuming that what you're rotating is the camera, not some object in the scene.
One problem is, if you only have a direction vector "forward" how do you move it? where is the right and left?
My approach in this case is to just take the cross product of "direction" and (0,1,0).
Now you can move the camera to the left and to the right using something like:
position = position + right * amount; //amount < 0 moves to the left
You can move forward using the "direction vector", but IMO it's better to restrict movement to a horizontal plane, so get the forward vector the same way we got the right vector:
forward = cross( up, right )
To be honest, this is somewhat of a hackish approach.
The proper approach is to use a more "sophisticated" data structure to represent the "orientation" of the camera, not just the forward direction. However, since you're just starting out, it's good to take things one step at a time.
All of these "actions" can be achieved using model-view matrix transformation functions. You should read about glTranslatef (panning), glScalef (zoom), glRotatef (rotation). You also should need to read some basic tutorial about OpenGL, you might find this link useful.
Generally there are three steps that are applied whenever you reference any point in 3d space within opengl.
Given a Local point
Local -> World Transform
World -> Camera Transform
Camera -> Screen Transform (usually a projection. depends on if you're using perspective or orthogonal)
Each of these transforms is taking your 3d point, and multiplying by a matrix.
When you are rotating the camera, it is generally changing the world -> camera transform by multiplying the transform matrix by your rotation/pan/zoom affine transformation. Since all of your points are re-rendered each frame, the new matrix gets applied to your points, and it gives the appearance of a rotation.