Gimbal Lock

Posted By: frazzle

Gimbal Lock - 12/30/07 11:32

Most of us programmers may have already encountered this annoying problem which is quite hard to get right There is already a topic about arbitrary rotation but it seems this solution only works if the angles are predetermened before runtime and thus changing the angles during runtime will still give an inaccurate rotation around the pan or z axis while tilt equals 90 or -90 degrees.

I've tried most methodes like c_rotate with setting the USE_AXISR, inverting the angles for local rotation, using ang_rotate and ang_add but none of it will work. This code gives the most accurate rotation:
Code:
 
var temp2[3];
vec_set(temp,vector(my.pan,0,0));
vec_rotate(temp,vector(-my.pan,0,0)); // local rotation by inverting the angle
vec_to_angle(temp2,temp); // converting from vec to ang
ang_rotate(test.pan,temp2); // rotating initial angle by entity's pan angle



The result of this code is that the entity rotates around his z-axis (panning) while tilt is 90 or -90 degrees but the rotation is not only around the z-axis but also around his x-axis(rolling) at the same time and too fast as well ^^
All help is welcome

Thanks in progress

Frazzle
Posted By: Futurulus

Re: Gimbal Lock - 12/30/07 19:45

What are you trying to accomplish with this -- i.e. what are temp, temp2, and my in this case?

I had this problem before because I needed my player to rotate arbitrarily in a zero-G game, but ang_rotate worked pretty well for me.
For example, if you want a player to rotate around its own Z-axis (pan), no matter how that axis is oriented, when the D key is pressed:
Code:
while(1)
{
//...

if(key_d)
{
ang_rotate(my.pan, vector(-5 * time_step, 0, 0));
}

//...
wait(1);
}

This might not be exactly what you want though...
Posted By: frazzle

Re: Gimbal Lock - 12/30/07 20:40

First of all, thank you for your input
Second, I tried this already several times and it indeed works which I knew afront as well but if seems that the rotation afterwards isn't quite accurate anymore when the tilt/roll/pan value of the enitity changes

I'm trying to make an entity rotate while standing on a wall so when the normal.z equals 0 and tilt equals 90 or -90 degrees.But I think I'll mesh around with ang_rotate abit more ^^
Btw, 'temp' is a predefined variable such as 'player'. 'Temp2' is a vector I used for putting through the angle towards the entity. 'My' is a predefined pointer I use for this entity.

Thanks in progress

Frazzle
Posted By: Futurulus

Re: Gimbal Lock - 12/30/07 23:16

Ah... let me see if I understand this.
Quote:

I'm trying to make an entity rotate while standing on a wall so when the normal.z equals 0


Your wall is vertical then...
Quote:

and tilt equals 90 or -90 degrees


...and your entity (a gun turret maybe?) is stuck to the side of the wall, facing either straight up or straight down. Is that right?
Quote:

if seems that the rotation afterwards isn't quite accurate anymore


You probably won't get pinpoint accuracy with 3 decimal places of precision, which is the best a var can manage.

With the bigger picture, though, I still don't understand what you are trying to do. I work better with a visual goal in mind, thinking about a gun turret or a spy camera or whatever. Unless that's proprietary information...
Posted By: Grafton

Re: Gimbal Lock - 12/31/07 04:58

It can be done, If I understand correctly what you mean. This DEMO of one of my ongoing projects demonstrates some possibilities and is made without using Julz's quaternions for GS, but I am working on a rewrite that will use that method instead. I would suggest you check into using them.
Posted By: Rhuarc

Re: Gimbal Lock - 12/31/07 05:16

Although a much bigger thing to tackle, it sometimes yields the most sure-shot way to get consistnet and unbreakable results:

http://en.wikipedia.org/wiki/Quaternion

Quaternions can be used to represent rotation without ugly grimbal lock- the downside is they are more complex and more process intense. You could easily store all of your angle information using quaternions and do your operations there, then convert the quaternion to a euler angle.

Just two cents
Posted By: vlau

Re: Gimbal Lock - 12/31/07 05:34

I have the similar problem too. jumpman has ask this
question about 2 months ago, I hope it can be
solved with liteC->atan2 but I'm not sure.
Posted By: frazzle

Re: Gimbal Lock - 12/31/07 09:24

@ Futurulus
Here's a visual

Ignore the numbers, that's for debugging issues.
As you can see, the entity is standing on a vertical wall as you have mentioned.
I'm trying to let it rotate about its z-axis. I got that part working correctly but say when I want to run up the ceiling or back at the floor. Then the angles will change due to ang_rotate giving an incorrect motion. But I think I'm getting close to a potential solution

@ Grafton

Thanks for the demo but I was already aware of this as well ^^
Quaternions are indeed the answer but I don't want to use them since I trying to create a wallwalking/ceilingwalking system which only uses 3dgs native angles (Euler).

@ Rhuarc

The downside you're talking about is also one of the problems. I've thought about using quaternions only when the tilt value of an entity equal 90 or -90. So when other tilt values are reached, using Euler's angles. But it's process intense like you mentioned thus using it only for that reason would be unlogic

@ vlau

Basically, I know all those topics since this past week, I've spend hours in searching for a solution on this forum. Some were helpful like the one you've mentioned But the only problem is that this code from the manual takes a direction vector into account which is the camera. Since my code is based pure on angles, I can't really use it ^^
About LC, I'm actually more a c-script fan

Thanks again for all of your input

Thanks in progress

Frazzle
Posted By: Shadow969

Re: Gimbal Lock - 12/31/07 12:12

Yep, i haven't managed to make aligning to ground work as i wanted. It works perfectly on walls and slopes, but if the wall has a pan non-equal to 0, 90, 180 or 270 aligning becomes innacurate and kinda random
Posted By: frazzle

Re: Gimbal Lock - 12/31/07 16:27

Indeed
But I think there's a methode that can solve it but it's abit a work around ^^

Cheers

Frazzle
Posted By: Futurulus

Re: Gimbal Lock - 01/05/08 02:10

<!-- Just ignore my rambling if you've solved it on your own. -->

Ah, wall-walking! Thanks for the screenshot.

I know how to work with a bunch of vectors here. This figures out a new "forward" vector for your character given an old "forward" vector, an old "floor" normal, and a new "wall" normal that you can get from c_move (untested):
Code:
var tempang[3];
var tempang2[3];

// in a function...
// figure out how the old normal needs to be rotated to change to the new normal
vec_to_angle(tempang, OldNormal);
vec_inverse(tempang);
vec_rotate(NewNormal, tempang);
// you could reuse tempang here but I used a different variable because it means something different now
vec_to_angle(tempang2, NewNormal);

// rotate the old forward vector the same way
vec_set(NewForward, OldForward);
vec_rotate(NewForward, tempang2);
// ...rest of function


The hard part is turning the new forward vector into an Euler angle. Using vec_to_angle would give you the right pan and tilt, but then you'd have to adjust roll.

You could easily figure out top and side vectors (top = NewNormal; left = NewForward CROSS NewNormal) if that info is needed. I've never had much luck converting vectors to Euler angles, though.
Posted By: frazzle

Re: Gimbal Lock - 01/05/08 10:12

Appriciate the input once again Futurulus
The methode like you described it seems logic if you think about it indeed but coverting a vector into an angle using vec_to_angle works good when not adjusting pan, tilt and roll at the same time which is quite difficult in a situation like GL. Therefore you need to inverse pan,tilt and roll to solve that part of the problem but eventually it will lead into inaccurate angles when shiften from normal again due to GL. Anyway, the methode I maded is good enough. It's located in the UR thread

Cheers

Frazzle
© 2024 lite-C Forums