Hello everyone,
I recently decided to implement a trackball/arcball rotation in my code.
The internet is full of tutorial about that so I found plenty of help, and I did implement the rotation,
only the results are not the ones that I expected and I wonder where or even if I did something wrong …
I guess that something is wrong in my code only I cannot find what, I probably lack the appropriate
knowledge, thus I decided to ask for help.
My problem is the following, I implemented the trackball rotation not to have mouse-based rotations
axis limitated the x, y and z axis, that was the case previously in my code using:
void on_pressed (int x, int y)
{
mouseX = x;
mouseY = y;
}
float cameraAngleX = 0.0;
float cameraAngleY = 0.0;
// on mouse motion I change the rotation angle ...
void on_motion (int x, int y)
{
cameraAngleY += (double) 0.5*(x - mouseX);
cameraAngleX += (double) 0.5*(y - mouseY);
render_scene ();
view -> mouseX = x;
view -> mouseY = y;
}
/// ... and later I rotate the scene accordingly
void render_scene ()
{
...
glRotated (cameraAngleY, 0.0, 1.0, 0.0);
glRotated (cameraAngleX, 1.0, 0.0, 0.0);
...
}
Now my new code for the trackball rotation:
#define SIZE_X 640
#define SIZE_Y 480
float dot_product (float vect_a[3], float vect_b[3])
{
int i;
float v;
v = 0.0;
for (i=0; i<3; i++)
{
v += vect_a[i]*vect_b[i];
}
return v;
}
void cross_product (float vect_a[3], float vect_b[3], float cross[3])
{
cross[0] = vect_a[1]*vect_b[2] - vect_a[2]*vect_b[1];
cross[1] = vect_a[2]*vect_b[0] - vect_a[0]*vect_b[2];
cross[2] = vect_a[0]*vect_b[1] - vect_a[1]*vect_b[0];
}
void normalize (float vect[3])
{
int i;
float mod_vect = 0.0;
for (i=0; i<3; i++) mod_vect += vect[i]*vect[i];
mod_vect = sqrt(mod_vect);
for (i=0; i<3; i++) vect[i] /= mod_vect;
}
void get_arc_ball_vector (int x, int y, float vect[3])
{
vect[0] = 2.0*x/SIZE_X - 1.0;
y =SIZE_Y - y;
vect[1] = 2.0*y/SIZE_Y - 1.0;
float norm_arc = vect[0]*vect[0] + vect[1]*vect[1];
if (norm_arc > 1.0)
{
vect[2] = 0.0;
}
else
{
vect[2] = sqrt(1.0 - norm_arc);
}
normalize (vect);
}
float arc_ball_init[3];
float arc_ball_new[3];
void on_pressed (int x, int y)
{
mouseX = x;
mouseY = y;
get_arc_ball_vector (x, y, arc_ball_init);
}
// on mouse motion I change the rotation angle ...
void on_motion (int x, int y)
{
float rot_angle;
float rot_axis[3];
get_arc_ball_vector (x, y, arc_ball_new);
rot_axis = cross_product (arc_ball_init, arc_ball_new);
if (norm(rot_axis) > 0.0)
{
rot_angle = acos(dot_product(arc_ball_init, arc_ball_new));
glRotatef (rot_angle, rot_axis[0], rot_axis[1], rot_axis[2]);
}
render_scene ();
}
My problem is the following: both methods give me exactly the same result, ie. rotations that are around
x, y and z axis … which is precisely what I would l like to avoid … I tried with quaternions and naturally
got the exact same result … I would really appreciate your help to understand what I am missing here.
Thanks in advance.
S.