Quote:
Original post by frob
Some good stuff.
That explanation of quaternions is one of the most helpful I've read. Thanks.
Quote:
Original post by frob
Some good stuff.
Quote:
Original post by Lode
About gimbal lock, my 3D engine uses only 3x3 matrices and 3x1 vectors, and I suffer no gimbal lock at all.
Quote:
Original post by Sneftel Quote:
Original post by Lode
About gimbal lock, my 3D engine uses only 3x3 matrices and 3x1 vectors, and I suffer no gimbal lock at all.
Gimbal lock is this ridiculous game development bogeyman which gets trotted out whenever the topic of rotations comes up. Ridiculous because 99% of game developers could use euler angles all their life and never actually run into gimbal lock. It's a subject which is of primary importance to robotics and aerospace engineers, and which only really intersects game development in certain special IK cases. Usually, game developers who say "gimbal lock" really just mean non-commutativity of rotations.
Quote:
Original post by Kambiz
You do not need quaternions or even matrixes to represent rotations in 3d. 3d Vectors are enough. We can just use the rotation operator Exp(phi X); phi is a 3d vector and X is the cross product. Exp(phi X) v will rotate the v vector around phi by the angel |phi|.
Exp(phi X) v = (1+1/2*phi X+...)v
#include<stdio.h>#include<math.h>struct _v3{ double x,y,z;};_v3 operator+(_v3 a,_v3 b){_v3 r;r.x=a.x+b.x;r.y=a.y+b.y;r.z=a.z+b.z;return r;}_v3 operator*(double k,_v3 v){_v3 r;r.x=k*v.x;r.y=k*v.y;r.z=k*v.z;return r;}_v3 cross(_v3 a,_v3 b){ _v3 r; r.x=a.y*b.z-a.z*b.y; r.y=-(a.x*b.z-a.z*b.x); r.z=a.x*b.y-a.y*b.x; return r;}_v3 cross2(_v3 a,_v3 b,int n){ if(0==n) return b; if(1==n) return cross(a,b); return(cross2(a,cross(a,b),n-1));}double fac(int n){ double r=1; if(0==n)return 1.0; for(int i=n;i>1;i--)r*=(double)i; return r;}double abs(_v3 v){return(sqrt(v.x*v.x+v.y*v.y+v.z*v.z));}int main(){ //let us rotate <1,0,0> around <1,1,1> by 2*pi/3 //phi=(Norm<1,1,1>)*2pi/3=<2pi/3/sqrt(3),...,...> _v3 phi={1.2092,1.2092,1.2092}; _v3 v={1,0,0}; _v3 r={0,0,0},t; //exp x = 1+x+x^2/2!+x^3/3!+... int i=0; do{ t=(1./fac(i))*cross2(phi,v,i); r=r+t; i++; }while(abs(t)>1e-6); printf("<%f,%f,%f>\n",r.x,r.y,r.z);}
@Lode To pass from an element z1 of IR^3 to an element z2 of IR^3, the first must be multiplied by a quaternion q ( z2 = q * z1 ).
Here's another way to see quaternions as complex numbers : Spherical-vectors and geometric interpretation of unit quaternions