PDA

View Full Version : Trackball - help

baconbeastnz
10-14-2008, 08:57 PM
Hi there! I'm a little confused about the maths behind this trackball routine below.

(1) Why do we map our points onto a hemisphere and not a sphere?
(2) What do the following lines calculate: (I understand the code, just not the geometry)
(3) Why are we converting all coords to range between -1 to 1.

void CTrackball::_tbPointToVector(int x, int y, int width, int height, float v[3])
{
float d, a;

// project x, y onto a hemi-sphere centered within width, height.
v[0] = (float) ((2.0 * x - width) / width);
v[1] = (float) ((height - 2.0 * y) / height);
d = (float) (sqrt(v[0] * v[0] + v[1] * v[1]));
v[2] = (float) (cos((3.14159265 / 2.0) * ((d < 1.0) ? d : 1.0))); // if d is smaller than 1 x by d, else 1
a = (float) (1.0 / sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]));
v[0] *= a;
v[1] *= a;
v[2] *= a;
}

then later on we take the difference between the old mouse position and the new mouse position and set up the angle to rotate the world by:

dx = current_position[0] - tb_lastposition[0];

dy = current_position[1] - tb_lastposition[1];
dz = current_position[2] - tb_lastposition[2];
tb_angle = (float) (90.0 * sqrt(dx * dx + dy * dy + dz * dz));

tb_axis[0] = tb_lastposition[1] * current_position[2] -
tb_lastposition[2] * current_position[1];

tb_axis[1] = tb_lastposition[2] * current_position[0] -
tb_lastposition[0] * current_position[2];

tb_axis[2] = tb_lastposition[0] * current_position[1] -
tb_lastposition[1] * current_position[0];

Why * by 90?

and finally applying it to the World:

void CTrackball::tbMatrix()
{
glPushMatrix();
glRotatef(tb_angle, tb_axis[0], tb_axis[1],tb_axis[2]);
glMultMatrixf((GLfloat *)tb_transform);
glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat*)tb_transform);
glPopMatrix();
glMultMatrixf((GLfloat *)tb_transform);
}

What does glGetFloatv actually do here?

Seems unnessecarily complex to me, I must be missing something.
AS I've made a much simpler version, which seems to work just as well.

xProportion = Xdisplacement / windowWidth;
glRotate((360 * xProportion), 0, 1,0)
// 360 = full rotation if user moves whole window width, just an arbitary scaling factor.

Then i do the same for Y. seems much simpler!