PDA

View Full Version : Quaternion lookat



{MSX}
05-01-2005, 10:22 AM
Hi! Anybody here knows about an algorithm for quaternion that orients it to look to a given vector ? (eventually with the up vector too)
Something like:

lookAt( target, up:TVector):TQuaternion

Thanks

Paulius
05-01-2005, 11:46 AM
If no one gets a better idea and you?¢_Tre not too lazy :wink: you could snap matrix to quaternion conversion code onto gluLookAt.
Mesa?¢_~s gluLookAt looks likes this:

void GLAPIENTRY
gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez,
GLdouble centerx, GLdouble centery, GLdouble centerz,
GLdouble upx, GLdouble upy, GLdouble upz)
{
GLdouble m[16];
GLdouble x[3], y[3], z[3];
GLdouble mag;

/* Make rotation matrix */

/* Z vector */
z[0] = eyex - centerx;
z[1] = eyey - centery;
z[2] = eyez - centerz;
mag = sqrt(z[0] * z[0] + z[1] * z[1] + z[2] * z[2]);
if (mag) { /* mpichler, 19950515 */
z[0] /= mag;
z[1] /= mag;
z[2] /= mag;
}

/* Y vector */
y[0] = upx;
y[1] = upy;
y[2] = upz;

/* X vector = Y cross Z */
x[0] = y[1] * z[2] - y[2] * z[1];
x[1] = -y[0] * z[2] + y[2] * z[0];
x[2] = y[0] * z[1] - y[1] * z[0];

/* Recompute Y = Z cross X */
y[0] = z[1] * x[2] - z[2] * x[1];
y[1] = -z[0] * x[2] + z[2] * x[0];
y[2] = z[0] * x[1] - z[1] * x[0];

/* mpichler, 19950515 */
/* cross product gives area of parallelogram, which is < 1.0 for
* non-perpendicular unit-length vectors; so normalize x, y here
*/

mag = sqrt&#40;x&#91;0&#93; * x&#91;0&#93; + x&#91;1&#93; * x&#91;1&#93; + x&#91;2&#93; * x&#91;2&#93;&#41;;
if &#40;mag&#41; &#123;
x&#91;0&#93; /= mag;
x&#91;1&#93; /= mag;
x&#91;2&#93; /= mag;
&#125;

mag = sqrt&#40;y&#91;0&#93; * y&#91;0&#93; + y&#91;1&#93; * y&#91;1&#93; + y&#91;2&#93; * y&#91;2&#93;&#41;;
if &#40;mag&#41; &#123;
y&#91;0&#93; /= mag;
y&#91;1&#93; /= mag;
y&#91;2&#93; /= mag;
&#125;

#define M&#40;row,col&#41; m&#91;col*4+row&#93;
M&#40;0, 0&#41; = x&#91;0&#93;;
M&#40;0, 1&#41; = x&#91;1&#93;;
M&#40;0, 2&#41; = x&#91;2&#93;;

M&#40;0, 3&#41; = 0.0;
M&#40;1, 0&#41; = y&#91;0&#93;;
M&#40;1, 1&#41; = y&#91;1&#93;;
M&#40;1, 2&#41; = y&#91;2&#93;;
M&#40;1, 3&#41; = 0.0;
M&#40;2, 0&#41; = z&#91;0&#93;;
M&#40;2, 1&#41; = z&#91;1&#93;;
M&#40;2, 2&#41; = z&#91;2&#93;;
M&#40;2, 3&#41; = 0.0;
M&#40;3, 0&#41; = 0.0;
M&#40;3, 1&#41; = 0.0;
M&#40;3, 2&#41; = 0.0;
M&#40;3, 3&#41; = 1.0;
#undef M
glMultMatrixd&#40;m&#41;;

/* Translate Eye to Origin */
glTranslated&#40;-eyex, -eyey, -eyez&#41;;

&#125;

Sly
05-01-2005, 11:51 AM
Sssh... if we give him the answer he might win the dog fight competition. :lol:

{MSX}
05-01-2005, 12:44 PM
Sssh... if we give him the answer he might win the dog fight competition. :lol:

:lol: :lol:
Just becouse i ask about quaternions, that are expecially useful with airplane models, that doesn't mean it's about the dog fight compo..
Well, in this case, it is :mrgreen:

Btw my entry is going on greatly.. just wait and see :P

{MSX}
05-01-2005, 12:48 PM
If no one gets a better idea and you?¢_Tre not too lazy :wink: you could snap matrix to quaternion conversion code onto gluLookAt.
Mesa?¢_~s gluLookAt looks likes this:


Umm that could be an idea.. but i'm way too lazy :P Also i'm not that good with matrices and i could make some bug..

WILL
06-01-2005, 12:54 AM
:lol:

{MSX}
07-01-2005, 09:25 AM
ok.. apart from jokes :mrgreen:
Any clue ? I need it quite a lot..

Thanks :P

savage
07-01-2005, 09:37 AM
Nicola,
If you are using JEDI-SDL, in the OpenGL directory you should find Mike Lischke's excellent Geometry.pas file which has all sorts of 3D functions including Quaternions.

IHTH.

{MSX}
07-01-2005, 12:21 PM
Nicola,
If you are using JEDI-SDL, in the OpenGL directory you should find Mike Lischke's excellent Geometry.pas file which has all sorts of 3D functions including Quaternions.

IHTH.

I've already looked there, but there is not a big support for quaternions. There are only basic functions.

I'm assembling a unit that is more complete, so btw if you want to use it on JEDI-SDL just ask. It's based on FastGEO for vectors and the like (but it can easily be changed)

{MSX}
08-01-2005, 04:21 PM
I've spotted this article (http://euclideanspace.com/maths/algebra/vectors/angleBetween/index.htm).
It tells something about how to obtain axis angle representation of the rotation of a given vector to another. It doesn't uses the up vector, but it can still be useful..

I tryed and implemented this:

v:=mul(a.position, b.position); // cross product
b.orientation.x:=v.x;
b.orientation.y:=v.y;
b.orientation.z:=v.z;
b.orientation.w:= magnitude(a.position) * magnitude(b.position) + dotproduct( unitvector(b.position), unitvector(a.position));
Q_normed(b.orientation);

It should orient b to a but it doesn't work..
Anyone interested in helping ? :P
Thanks

{MSX}
10-01-2005, 09:25 PM
I've finally resolved the problem.. I had to use a middle step with a matrix.. That could eventually optimized..

Here's the procedure:


function matrixLookAt(const dir, up:TVector3D):TMatrix3;
var xAxis, normUp, normDir:TVector3d;
begin
// calculate the x axis, and normalize it
xAxis := UnitVector(Mul(up,dir));
// Recalculate up so that it is perpendicular to dir (and normalize it)
normup := UnitVector(Mul(dir,xAxis));
// normalize dir
normdir := UnitVector(dir);

result[0, 0] := xAxis.x;
result[1, 0] := xAxis.y;
result[2, 0] := xAxis.z;

result[0, 1] := normup.x;
result[1, 1] := normup.y;
result[2, 1] := normup.z;

result[0, 2] := normdir.x;
result[1, 2] := normdir.y;
result[2, 2] := normdir.z;
end;

function Q_LookAt(const dir, up:TVector3D):TQuaternion;
var m:TMatrix3;
begin
m:=matrixLookAt(dir, up);
transpose(m);
result:=M2Q(m);
end;



Now i really need some rest.. :drunk: