1. rotating around object (looat)

I need to rotate an object (bezier surface).
I wish to use glLookAt instead of rotatef.

i started with :

Code:
```// clear the screen & depth buffer
glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
// clear the previous transform
// set the camera position
gluLookAt(	xLookAt,yLookAt,zLookAt,	//	eye pos
0,0,0,	//	aim point
0,1,0);	//	up direction```
and :
Code:
```		if ((x < -6.28) || (x > 6.28))
{
x=0;
xLookAt = 0;
break;
}
x -= 0.1;
xLookAt = cos(x) * sin (z);
break;```
I'm using 6.28 as 2 PI and i wish to go around an object.
the problem is that it changes the direction of movment instead continue move.

i used the next code :
Code:
```//------------------------------------------------------------
/// \file	Main.cpp
/// \author	Rob Bateman
/// \date	9-feb-2005
/// \brief	This is a very simple example of a bezier patch
//------------------------------------------------------------
#include <stdlib.h>
#include <GL/glut.h>
#include <math.h>
#include <stdio.h>

struct Point {
float x;
float y;
float z;
};

/// 4x4 grid of points.
Point Points[4][4] = {
{
{ 10,0,10 },
{  5,0,10 },
{ -5,0,10 },
{-10,0,10 }
},

{
{ 10,0,5 },
{  5,6,5 },
{ -5,6,5 },
{-10,0,5 }
},

{
{ 10,0,-5 },
{  5,6,-5 },
{ -5,6,-5 },
{-10,0,-5 }
},

{
{ 10,0,-10 },
{  5,0,-10 },
{ -5,0,-10 },
{-10,0,-10 }
}

};

unsigned int num_knots_u=8;
unsigned int num_knots_v=8;
unsigned int num_cvs_u=4;
unsigned int num_cvs_v=4;
unsigned int degree_u=3;
unsigned int degree_v=3;
unsigned int order_u=degree_u+1;
unsigned int order_v=degree_v+1;

float knots_u[] = {0,0,0,0,1,1,1,1};
float knots_v[] = {0,0,0,0,1,1,1,1};

unsigned int LOD=20;

float MinU() {
return knots_u[degree_u];
}

float MinV() {
return knots_v[degree_v];
}

float MaxU() {
return knots_v[num_knots_u-degree_u];
}

float MaxV() {
return knots_v[num_knots_v-degree_v];
}

//------------------------------------------------------------	CoxDeBoor()
//

float CoxDeBoor(float u,int i,int k,const float* Knots) {
if(k==1)
{
if( Knots[i] <= u && u <= Knots[i+1] ) {
return 1.0f;
}
return 0.0f;
}

float Den1 = Knots[i+k-1] - Knots[i];
float Den2 = Knots[i+k] - Knots[i+1];
float Eq1=0,Eq2=0;
if(Den1>0) {
Eq1 = ((u-Knots[i]) / Den1) * CoxDeBoor(u,i,k-1,Knots);
}

if(Den2>0) {
Eq2 = (Knots[i+k]-u) / Den2 * CoxDeBoor(u,i+1,k-1,Knots);
}
return Eq1+Eq2;
}

//------------------------------------------------------------	CalculateU()
//

Point CalculateU(float t,int row) {
Point p = {0,0,0};
// sum the effect of all CV's on the curve at this point to
// get the evaluated curve point
//
for(unsigned int i=0;i!=num_cvs_u;++i) {
// calculate the effect of this point on the curve
float Val = CoxDeBoor(t,i,order_u,knots_u);
if(Val>0.001f) {
// sum effect of CV on this part of the curve
p.x += Val * Points[row][i].x;

p.y += Val * Points[row][i].y;

p.z += Val * Points[row][i].z;

}

}

return p;

}

//------------------------------------------------------------	CalculateV()

//

Point CalculateV(float t,Point* pnts) {

Point p = {0,0,0};

// sum the effect of all CV's on the curve at this point to

// get the evaluated curve point

//

for(unsigned int i=0;i!=num_cvs_v;++i) {

// calculate the effect of this point on the curve

float Val = CoxDeBoor(t,i,order_v,knots_v);

if(Val>0.001f) {

// sum effect of CV on this part of the curve

p.x += Val * pnts[i].x;

p.y += Val * pnts[i].y;

p.z += Val * pnts[i].z;

}

}

return p;

}

//------------------------------------------------------------	Calculate()

//

Point Calculate(float u,float v) {

Point* temp = new Point[num_cvs_v];

for(unsigned int i=0;i!=num_cvs_v;++i) {

// first treat the surface as a set of 4 curves. Calculate

// a point on each of the curves and store the result.

//

temp[i] = CalculateU(u,i);

}

// having got 4 points, we can use it as a bezier curve

// to calculate the v direction

//

Point p = CalculateV(v,temp);

delete [] temp;

return p;

}

//------------------------------------------------------------	OnReshape()

//

void OnReshape(int w, int h)

{

if (h==0) {

h=1;

}

// set the drawable region of the window

glViewport(0,0,w,h);

// set up the projection matrix

glMatrixMode(GL_PROJECTION);

// just use a perspective projection

gluPerspective(45,(float)w/h,0.1,100);

// go back to modelview matrix so we can move the objects about

glMatrixMode(GL_MODELVIEW);

}

//------------------------------------------------------------	Draw()

//

float x = 5;

float alpha = 0;

float y = 16;

float z = 20 ;
float xLookAt = x;
float yLookAt = y;
float zLookAt = z;

void OnDraw() {

// clear the screen & depth buffer

glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);

// clear the previous transform

// set the camera position

gluLookAt(	xLookAt,yLookAt,zLookAt,	//	eye pos

0,0,0,	//	aim point

0,1,0);	//	up direction

glColor3f(1,0,1);

glPointSize(2);

glBegin(GL_POINTS);

// use the parametric time value 0 to 1

for(int i=0;i!=LOD;++i) {

// calculate the parametric u value

float u = (MaxU()-MinU())*(float)i/(LOD-1) + MinU();

for(int j=0;j!=LOD;++j) {

// calculate the parametric v value

float v = (MaxV()-MinV())*(float)j/(LOD-1) + MinV();

// calculate the point on the surface

Point p = Calculate(u,v);

// draw point

glVertex3f(p.x,p.y,p.z);

}

}

glEnd();

// currently we've been drawing to the back buffer, we need

// to swap the back buffer with the front one to make the image visible

glutSwapBuffers();

}

//------------------------------------------------------------	OnInit()

//

void OnInit() {

// enable depth testing

glEnable(GL_DEPTH_TEST);

}

//------------------------------------------------------------	OnExit()

//

void OnExit() {

}

//------------------------------------------------------------	OnKeyPress()

//

void OnKeyPress(unsigned char key,int,int) {

switch(key) {

// increase the LOD

case '+':

++LOD;

break;

// decrease the LOD

case '-':

--LOD;

// have a minimum LOD value

if (LOD<3)

LOD=3;

break;

case 'a':

//		glPop

break;

case 'b':
if ((x < -6.28) || (x > 6.28))
{
x=0;
xLookAt = 0;
break;
}
x -= 0.1;
xLookAt = cos(x) * sin (z);
break;

default:

break;

}

// ask glut to redraw the screen for us...
//x = cos(y) * sin(z);

glutPostRedisplay();

}

//------------------------------------------------------------	main()

//

int main(int argc,char** argv) {

// initialise glut

glutInit(&argc,argv);

// request a depth buffer, RGBA display mode, and we want double buffering

glutInitDisplayMode(GLUT_DEPTH|GLUT_RGBA|GLUT_DOUBLE);

// set the initial window size

glutInitWindowSize(640,480);

// create the window

glutCreateWindow("Bezier Curve: +/- to Change Level of Detail");

// set the function to use to draw our scene

glutDisplayFunc(OnDraw);

// set the function to handle changes in screen size

glutReshapeFunc(OnReshape);

// set the function for the key presses

glutKeyboardFunc(OnKeyPress);

// run our custom initialisation

OnInit();

// set the function to be called when we exit

atexit(OnExit);

// this function runs a while loop to keep the program running.

glutMainLoop();

return 0;

}```

2. That double spaced code is just hard to read. Whitespace is good, but you can have too much of a good thing.

A suggestion: don't create global variables with short names like "x" and "y". You might use them by accident.

I'm using 6.28 as 2 PI
You could use the semi-non-standard M_PI from <math.h> or define PI yourself if you wanted to. For example, I like to use
Code:
```#ifdef PI
#define CONSTANT_PI PI
#elif defined(M_PI)
#define CONSTANT_PI M_PI
#else
#define CONSTANT_PI 3.14159265358979323846264338327950288419716939937510582097
#endif```
Or you could calculate PI dynamically with something like
Code:
`double PI = atan(1) * 4;`
As for your question . . . sorry, but I have no idea.

3. To rotate around something always translate then rotate.

4. So not to use glLookAt ?

moment i didn't understant :
if i use glRotate then i rotate the object while i wish to rotate only the camera.

5. What are you trying to do? Bubba is recommending you make a translation matrix and then multiply it by a rotation matrix, as that is how you would rotate one object about another. But for a camera, glLookAt, or more technically a view matrix will do the trick.

edit:

Was just looking at your code, it doesn't seem quite right.

Code:
```if ((x < -6.28) || (x > 6.28))
{
x=0;
xLookAt = 0;
break;
}
x -= 0.1;
xLookAt = cos(x) * sin (z);
break;```
You're not setting yLookAt, only x. I would write my code like this.

Code:
```   angle-=0.1;
if(angle<0)
angle+=6.28;
I added a radius variable in there, and changed 'x' to the more accurate 'angle', because my programmer conscience was hurting.

6. Still same effect back and forth .
Also why do you change the y factor ?

i wish to rotate around opengl y axis (math z axis).

I think that it has connection to the fact cos is a par function ( same value for x and -x) .

7. Perhaps a little bit of a math primer might help. I recommend buying a book on 3D mathematics from www.amazon.com. www.gamedev.net has several recommendations in their articles and books section that will guide you through the maze of books that are available.

Given what I've seen here I don't think diving into rotations and translations would even help you at this point.

8. A bit off topic, but still within I think?

Is there any other way to rotate a mesh then using a matrix?

9. Is there any other way to rotate a mesh then using a matrix?
Yes. A quaternion would do, and is faster in most cases.
Still same effect back and forth .
I'm not too sure what that means, the code I wrote would make the camera rotate in a circle. Given, I haven't read the large amount of code on the lower end of your post.

10. [Fixed] or i hate typos

First of all thnx for all the great help and special thanks to dimtrios5000 and Jarik D

The fixed code (the new parts are ):

Code:
```	xLookAt = z * cos(y) * sin(x);
yLookAt = z * sin(y);
zLookAt = -1 * z * cos(y) * cos(x);```
By that you fix the back and forth rotation
next for some reason i didn't noticed that i use 6.8 instead of 6.28 (the "glitch" source).

11. That code will gimbal lock.

12. Sorry for asking (not native English speaker ) what is a "gimbal lock " ?

I tried to google and understand that it has to do with Gyroscopes.
In this code i had a problem to rotate around and object but to keep the angle to the base the same .

13. Gimbal lock is when one or more axes are mapped onto each other. If you think of 3D rotations as 3 concentric rings, gimbal lock is when two or more of those rings line up. At this point a rotation on one axis will also yield a rotation on another axis. With Euler angles there is no way to avoid gimbal lock.

In order to correct this you can use quaternions or you can perform axis-angle rotations. Both of these operate on the principle of rotating around an arbitrary axis as opposed to rotating around one of the three cardinal axes.

Here is Direct3D code to rotate around the x axis. Perhaps others here could convert this to OpenGL code for you.
Code:
```D3DXVECTOR3 g_vecRight;
D3DXVECTOR3 g_vecUp;
D3DXVECTOR3 g_vecLook;
D3DXVECTOR3 g_vecPos;

//Reset all vectors
void ResetVectors()
{
g_vecRight = D3DXVECTOR3(1.0f,0.0f,0.0f);
g_vecUp = D3DXVECTOR3(0.0f,1.0f,0.0f);
g_vecLook = D3DXVECTOR3(0.0f,0.0f,1.0f);
g_vecPos = D3DXVECTOR3(0.0f,0.0f,0.0f);
}

//Make all vectors orthonormal to each other - 90 degrees to each other
void MakeOrtho()
{
D3DXVec3Normalize(&g_vecLook,&g_vecLook);

D3DXVec3Cross(&g_vecUp,&g_vecLook,&g_vecRight);
D3DXVec3Normalize(&g_vecUp,&g_vecUp);

D3DXVec3Cross(&Right,&Up,&Look);
D3DXVec3Normalize(&Right,&Right);
}

//Pitch - rotate about the x or right axis
{
MakeOrtho();

D3DXMATRIX matRotX;

D3DXVec3TransformCoord(&g_vecUp,&g_vecUp,&matRotX);
D3DXVec3TransformCoord(&g_vecLook,&g_vecLook,&matRotX);
}

//Get the camera view matrix
void getViewMatrix(D3DXMATRIX *outMat)
{
MakeOrtho();

float x = -D3DXVec3Dot(&g_vecPos, &g_vecRight);
float y = -D3DXVec3Dot(&g_vecPos, &g_vecUp);
float z = -D3DXVec3Dot(&g_vecPos, &g_vecLook);

(*outMat)(0,0) = g_vecRight.x;
(*outMat)(1,0) = g_vecRight.y;
(*outMat)(2,0) = g_vecRight.z;
(*outMat)(3,0) = x;

(*outMat)(0,1) = g_vecUp.x;
(*outMat)(1,1) = g_vecUp.y;
(*outMat)(2,1) = g_vecUp.z;
(*outMat)(3,1) = y;

(*outMat)(0,2) = g_vecLook.x;
(*outMat)(1,2) = g_vecLook.y;
(*outMat)(2,2) = g_vecLook.z;
(*outMat)(3,2) = z;

(*outMat)(0,3) = 0.0f;
(*outMat)(1,3) = 0.0f;
(*outMat)(2,3) = 0.0f;
(*outMat)(3,3) = 1.0f;
}

//Get the object view matrix (transpose of the camera view matrix)
void getObjectMatrix(D3DXMATRIX *outMat)
{
MakeOrtho();

(*outMatrix)(0,0) = g_vecRight.x;
(*outMatrix)(1,0) = g_vecUp.x;
(*outMatrix)(2,0) = g_vecLook.x;
(*outMatrix)(3,0) = g_vecPos.x;//x;

(*outMatrix)(0,1) = g_vecRight.y;
(*outMatrix)(1,1) = g_vecUp.y;
(*outMatrix)(2,1) = g_vecLook.y;
(*outMatrix)(3,1) = g_vecPos.y;//y;

(*outMatrix)(0,2) = g_vecRight.z;
(*outMatrix)(1,2) = g_vecUp.z;
(*outMatrix)(2,2) = g_vecLook.z;
(*outMatrix)(3,2) = g_vecPos.z;//z;

(*outMatrix)(0,3) = 0.0f;
(*outMatrix)(1,3) = 0.0f;
(*outMatrix)(2,3) = 0.0f;
(*outMatrix)(3,3) = 1.0f;
}```
MakeOrtho() is used because the vectors will become skewed due to floating point imprecision.