how to control rotation use mouse based on Quaternion

is there any examples i can download?
any advice is welcome!

Get some code at



Of course it depends on what kind of rotation you want, but this works for me and creates a similar rotation to the one that seems to be used in many other 3d programs as well. I assume you already know how to use quaternions to rotate around an arbitary axis, the rest goes as follows:

For a view I have eye and target positions and an up vector. In this case the up vector needs to be propotional to the eye->target vector, otherwise you’ll get crappy euler style rotation.

Now, let’s say you have dx and dy refering to the amounts the mouse x and y have been changed. From those you derive angleX and angleY by scaling with a convinient factor.

Let v be vector from target to eye. First rotate v angleX degrees around the view’s up vector. Then get a right vector, being the cross product of up and v. Then rotate both v and up angleY degrees around the right vector.

Finally set the new eye position to target+v. That’s it, I hope it helps.


Originally posted by ruixp:
is there any examples i can download?
any advice is welcome!

thanks,Rob Fletcher&JustHanging
i use gluLookat
to move eye in 3d scene,i dont’ know the relationship between 2d mouse and 3d scene?

assume that
when i draw scene,i use


void CStratumVisView::OnLButtonDown(UINT nFlags, CPoint point)
glMouseDownX = point.x;
glMouseDownY = point.y;
gbLeftMouse = true;

void CStratumVisView::OnLButtonUp(UINT nFlags, CPoint point)
gbLeftMouse = false;

void CStratumVisView::OnMouseMove(UINT nFlags, CPoint point)
int dx,dy;
dx = glMouseDownX - point.x;
dy = glMouseDownY - point.y;
glMouseDownX = point.x;
glMouseDownY = point.y;

i don’t know how to determine witch axis ,my eye will rotate with?

who can tell me how to fill ??? in my code

Hi, these equations can help you…

mouseMove( AUX_EVENTREC *event )
x_old = xPos;
y_old = yPos;

xPos = event->data[AUX_MOUSEX];
yPos = event->data[AUX_MOUSEY];

/** Right/Left **/

	if (fabs(xPos-x_old) > fabs(yPos-y_old))
	  if (xPos > x_old)
		incx -= 0.5f;
		if (incx < 0.0f) incx = 359.5f;
		incx += 0.5f;
		if (incx > 359.5f) incx = 0.0f;
	}          // UP/DOWN
	else if (yPos > y_old)
	  pos[2] -= 5.0f;
	else pos[2] += 5.0f;
pos[0]= eye[0]+1000.0f* (GLfloat)cos((incx+90.0f)*2RAD);
pos[1] = eye[1]+1000.0f*(GLfloat)sin((incx+90.0f)*2RAD);
hdg = 360.0f - incx;


	if (yPos < y_old)
		eye[0] += (GLfloat)(cos((incx+90.0f)*2RAD)*10.0f);
		eye[1] += (GLfloat)(sin((incx+90.0f)*2RAD)*10.0f);
		eye[0] -= (GLfloat)(cos((incx+90.0f)*ARAD)*10.0f);
		eye[1] -= (GLfloat)(sin((incx+90.0f)*ARAD)*10.0f);


thanks cirityone!
your methods just like using keyboards to control 3d scene,but i want to control the rotation only by left button of mouse

any advice are welcome

So what’s wrong with the algorithm I gave you? Just code it and plug it in the ??? place in your mouseMove routine. If you understand quaternions it should be very straightforward.


i think your algrothim is just what i want!!

do u have any examples to share?

i really don’t have much knowledge about quantion,just one of my friends tell me that,
so i want to get help from you

Well, I guess I could post you some Delphi code when I get home… Would that help? It’s all pretty close to c/c++.


i am glad to get help from you,thanks!

Ok, let’s see. Here are the contents of my mousemove routine. The idea is to rotate the eye around the target based on the mouse movements:

procedure TPanTool.mouseDrag(x, y : integer; view : TViewport);
a1, a2 : float;
v, r : vector;
// Determine rotation angles from the change in mouse position

// Rotate the target->eye vectoraround the up vector

v:=vectorTo(, view.eye);
v:=rotateAround(a1, v, view.up);

// Determine the right vector and rotate the target->eye and up around it

r:=cross(view.up, v);
v:=rotateAround(a2, v, r);
view.up:=rotateAround(a2, view.up, r);

// Set the new eye position and repaint

view.eye:=vectorSum(, v);
View.caption:=‘Free view’;

// Update the mouse current position


And then the tricky rotation around an arbitary axis:

function rotateAround(an : float; vec, axis : vector): vector;
temp, v : vector;
mat : matrix4;
x, y, z, w : float;
a : float;
// Make a quaternion from the angle and the axis
v:=vMult(normalize(axis), sin(a));
x:=v[0]; y:=v[1]; z:=v[2]; w:=cos(a);

// Construct a transformation matrix from the quaternion

mat[0, 0]:=sqr(w)+sqr(x)-sqr(y)-sqr(z);
mat[1, 0]:=2xy+2wz;
mat[2, 0]:=2xz-2wy;
mat[3, 0]:=0;

mat[0, 1]:=2xy-2wz;
mat[1, 1]:=sqr(w)-sqr(x)+sqr(y)-sqr(z);
mat[2, 1]:=2yz+2wx;
mat[3, 1]:=0;

mat[0, 2]:=2xz+2wy;
mat[1, 2]:=2yz-2wx;
mat[2, 2]:=sqr(w)-sqr(x)-sqr(y)+sqr(z);
mat[3, 2]:=0;

mat[0, 3]:=0;
mat[1, 3]:=0;
mat[2, 3]:=0;
mat[3, 3]:=sqr(w)+sqr(x)+sqr(y)+sqr(z);

// Return the original vector transformed by the matrix

rotateAround:=transform4(vec, mat);

And in case you don’t know how to transform a vector by a 4x4 matrix,

function transform4(v : vector; mat : matrix4): vector;
temp : vector;
w : float;
w:=v[0]*mat[0, 3]+v[1]*mat[1, 3]+v[2]*mat[2, 3]+mat[3, 3];

temp[0]:=(v[0]*mat[0, 0]+v[1]*mat[1, 0]+v[2]*mat[2, 0]+mat[3, 0])/w;
temp[1]:=(v[0]*mat[0, 1]+v[1]*mat[1, 1]+v[2]*mat[2, 1]+mat[3, 1])/w;
temp[2]:=(v[0]*mat[0, 2]+v[1]*mat[1, 2]+v[2]*mat[2, 2]+mat[3, 2])/w;

That should be the essentials, the rest of the functions are just basic vector manipulation functions. If you code in c, you’re going to have to use one dimensional arrays for the matrice and pass pointers to the functions to be able to return vectors. Otherwise it should be easy to translate.

I hope that helps,


Hi JustHanging
thank u very much ,i will try based on your codes!