syoyo / tinyobjloader-c

Header only tiny wavefront .obj loader in pure C99
412 stars 60 forks source link

No need for the trig when creating quaternions #1

Open ratchetfreak opened 8 years ago

ratchetfreak commented 8 years ago

https://github.com/syoyo/tinyobjloader-c/blob/master/examples/viewer/trackball.c#L177

here you end up doing a asin and then a sin and cos on the result.

However to get a quaternion that rotates from one direction v1 to another v2 you only need to do

float q[4];
vnorm(v1);
vnorm(v2);
q[3]  = vdot(v1, v2) +1;
vcross(v1, v2, q); 
normalize_quat(q);

The plus 1 on the dot product is to get the quaternion representing the half rotation than when you would take just the dot and cross.

On the note of normalize: the magnitude you are dividing with should be the sqrt of the dot product with itself.

You can also opt to not do the normalize of the quaternion (and spare the sqrt) and adjust the matrix generation by dividing each q[...] * q[...] with q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]

syoyo commented 8 years ago

trackball.c is grabbed from famous and legacy OpenGL example code, and I'm just using it. Its just working so I have no strong reason to improve it.

Also I have no strong reason to stick to using trackball.c once there is a cleaner & recent good implementation of trackball functionality.