Using quaternions

Derrik
Posts: 63
Joined: Wed Aug 14, 2013 8:28 pm

Using quaternions

Post by Derrik » Sat Oct 18, 2014 12:22 pm

I have a model loaded, but I'm having trouble rotating it correctly in 3D space.

When using Euler angles the axis change after each rotation:

Code: Select all

glRotatef(angleX, 1.0f, 0.0f, 0.0f);
glRotatef(angleY, 0.0f, 1.0f, 0.0f);
glRotatef(angleZ, 0.0f, 0.0f, 1.0f);
If I reorder them, the resultant orientation changes because the axises change during each rotation. I don't want this behavior in my rotations.

I have read that quaternions will solve this problem.

However, when trying to implement a quaternion library (http://www.sacredsoftware.net/tutorials ... ions.xhtml) the model was translated off-screen.

Code: Select all

Quaternion q;

int main(void) {
	q = Quaternion_identity();
	
	while(1) {
		m4x4 m = Quaternion_toMatrix(q);
		
		int i;
		for(i = 0; i < 4 * 4; i++) {
			printf("%d %d\n", i, m.m[i]);
		}
		
		glMultMatrix4x4(&m);
	}
}
I figured out that the issue was because glMultMatrix4x4 expects a matrix to the 12 bit fractional part (<< 12). I came across the same problem when using trigonometric functions.

I experimented with the fixedToFloat and floatToFixed macros. For example I discovered that the following will give you a regular sine implementation:

Code: Select all

fixedToFloat(sinLerp(degreesToAngle(angle)), 12);
However I've been battling these conversions for several hours each day and still can't get a working implementation of quaternions. I keep getting odd artifacts such as stretching of my model or just translating it off-screen completely.

Has anyone been able to get quaternions working with VideoGL? Please help!

elhobbs
Posts: 358
Joined: Thu Jul 02, 2009 1:19 pm

Re: Using quaternions

Post by elhobbs » Sat Oct 18, 2014 2:18 pm

do you have a sample with code that you could share with people?

Derrik
Posts: 63
Joined: Wed Aug 14, 2013 8:28 pm

Re: Using quaternions

Post by Derrik » Sat Oct 18, 2014 7:08 pm

Here's what I've got at the moment:

http://www.321webs.com/download/80285.htm

As you can see from the code, I'm really not sure of what I should be doing.

Thanks for the help.

elhobbs
Posts: 358
Joined: Thu Jul 02, 2009 1:19 pm

Re: Using quaternions

Post by elhobbs » Sat Oct 18, 2014 8:50 pm

I think your main issue is dealing with fixed point numbers. There is no automatic conversion to and from floats - and you have a lot of mixing of the two in your code. I have not fixed all of the code - just the bare minimum needed to get the teapot to spin around the y axis. you should be able to apply the changes to the rest of the code.
Attachments
Quaternions.zip
(37.74 KiB) Downloaded 380 times

Derrik
Posts: 63
Joined: Wed Aug 14, 2013 8:28 pm

Re: Using quaternions

Post by Derrik » Sun Oct 19, 2014 8:19 pm

elhobbs wrote:I think your main issue is dealing with fixed point numbers. There is no automatic conversion to and from floats - and you have a lot of mixing of the two in your code. I have not fixed all of the code - just the bare minimum needed to get the teapot to spin around the y axis. you should be able to apply the changes to the rest of the code.
Thank you! This has helped me a lot! I should definitely be able to fix the rest of the code now.

Derrik
Posts: 63
Joined: Wed Aug 14, 2013 8:28 pm

Re: Using quaternions

Post by Derrik » Mon Oct 20, 2014 4:40 pm

I came across a problem. I need to implement a quaternion to euler function, however all of the formulas I have found online rely on atan or atan2. Unfortunately libnds does not have any inverse tan functions. Is there a work around for this?

Many thanks once again!

elhobbs
Posts: 358
Joined: Thu Jul 02, 2009 1:19 pm

Re: Using quaternions

Post by elhobbs » Mon Oct 20, 2014 5:43 pm

you can use the version in <math.h> - you will need to add libm to your make file. add -lm to LIBS after -lnds9
you will need to do some conversion of input/outputs to/from fixed/float etc.

Derrik
Posts: 63
Joined: Wed Aug 14, 2013 8:28 pm

Re: Using quaternions

Post by Derrik » Tue Oct 21, 2014 6:19 pm

I've given it a go but sadly it's not as simple as:

Code: Select all

#define atanLerp(a) ((int32)(atan((double)a / (double)4096.0) * (double)4096.0))
I tried to convert the radians to degrees and then convert the degrees to a DS angle with:

Code: Select all

#define atanLerp(a) degreesToAngle(atan((double)a / (double)4096.0) * (M_PI / 180.0))
But unfortunately this doesn't work either, so I'm not really sure where to go from here.

Derrik
Posts: 63
Joined: Wed Aug 14, 2013 8:28 pm

Re: Using quaternions

Post by Derrik » Tue Oct 21, 2014 7:53 pm

I was able to find an atan2Lerp function here:

http://www.coranac.com/2009/02/on-arctangent/

All I need now is a function which moves the model at the angle that it is rotated at (by the quaternion).

So first of all I need a quaternion to euler function, I found one here:

http://www.euclideanspace.com/maths/geo ... /index.htm

And tried to modify it for fixed point numbers:

Code: Select all

vect3D Quaternion_toEuler(Quaternion q) {
	//http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/index.htm
	
	vect3D v;
	
	ulong test = mulf32(q.x, q.y) + mulf32(q.z, q.w);
	if(test > floatToFixed(0.499f, 12)) { // singularity at north pole
		v.x = 2 * atan2(q.x, q.w);
		v.y = floatToFixed(M_PI / 2.0f, 12);
		v.z = 0;
		return v;
	}
	if(test < floatToFixed(-0.499f, 12)) { // singularity at south pole
		v.x = -2 * atan2(q.x, q.w);
		v.y = floatToFixed(-M_PI / 2.0f, 12);
		v.z = 0;
		return v;
	}
	
    ulong sqx = mulf32(q.x, q.x);
    ulong sqy = mulf32(q.y, q.y);
    ulong sqz = mulf32(q.z, q.z);
	
    v.x = atan2Lerp(2 * mulf32(q.y, q.w) - 2 * mulf32(q.x, q.z), (1 << 12) - 2 * sqy - 2 * sqz);
	v.y = asinLerp(2 * test);
	v.z = atan2Lerp(2 * mulf32(q.x, q.w) - 2 * mulf32(q.y, q.z), (1 << 12) - 2 * sqx - 2 * sqz);
	
	return v;
}
But it isn't working. Did I miss something?

elhobbs
Posts: 358
Joined: Thu Jul 02, 2009 1:19 pm

Re: Using quaternions

Post by elhobbs » Wed Oct 22, 2014 1:31 am

why do you have a mixture of atan2 (which is looking for doubles) and atan2Lerp(which is looking for fixed point)?

Post Reply

Who is online

Users browsing this forum: No registered users and 19 guests