Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Equivalent Rotations not equal

Keiki Lemieux
I make HUDDLES
Join date: 8 Jul 2005
Posts: 1,490
03-20-2006 13:01
This rotation: <-0.50000, -0.50000, -0.50000, -0.50000> and this rotation <0.50000, 0.50000, 0.50000, 0.50000> are equivalent rotations. They look identical on the screen if you have two cubes each with one of these.

Anyway, I'm making a new toy and I need to compare rotations of cubes. I need a way to compare these equivalent rotations. They seem obvious when I look at them on the screen, but is there some easy way to compare too rotations like finding the absolute rotation?
_____________________
imakehuddles.com/wordpress/
paulie Femto
Into the dark
Join date: 13 Sep 2003
Posts: 1,098
I don't know if this helps
03-20-2006 13:16
If you read these two different rotations to a string, you get the negative of the specified rotation. What I mean is, if you use this line:

llSay(0,"rotation="+(string)llGetRot());
on a rotation of <-0.50000, -0.50000, -0.50000, -0.50000>
you get
rotation=<0.50000, 0.50000, 0.50000, 0.50000>

and if you use the same line:
llSay(0,"rotation="+(string)llGetRot());
on a rotation of <0.50000, 0.50000, 0.50000, 0.50000>
you get
rotation=<-0.50000, -0.50000, -0.50000, -0.50000>

So, you could read em to a string and you would know that the actual rotation was the opposite of what the string says.

I'm no math whiz, so maybe someone else can explain why.
_____________________
REUTERS on SL: "Thirty-five thousand people wearing their psyches on the outside and all the attendant unfettered freakishness that brings."
Seifert Surface
Mathematician
Join date: 14 Jun 2005
Posts: 912
03-20-2006 14:12
IIRC the deal is that the mapping from unit quaternions to 3d rotations is 2 to 1. Two unit quaternions a and b represent the same 3d rotation if a is plus or minus b.

If you want to tell if quaternions a and b are "near" to each other, then its probably good enough to check that a.x is near to b.x, and the same for a.y, a.z and a.s. Then to check if two rotations are near to each other, you check if a is near to b, and then you check if a is near to -b.

Hope that makes sense.
_____________________
-Seifert Surface
2G!tGLf 2nLt9cG
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
03-20-2006 16:45
I think you can look at the angle between them and see how close it is to zero.

Like you should be telling if two vectors are "the same" if the distance between them is "small enough".
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
03-20-2006 18:03
Your quaternions don't even have to be unit quaternions for this to work.

CODE

integer SameAngle(rotation a, rotation b)
{
return llRot2Angle(a/b) < 0.000872664625997164;// 1/10th of a degree
}
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river.
- Cyril Connolly

Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence.
- James Nachtwey
Seifert Surface
Mathematician
Join date: 14 Jun 2005
Posts: 912
03-20-2006 18:33
From: Strife Onizuka
Your quaternions don't even have to be unit quaternions for this to work.
(although you're doing something weird if your quaternions aren't unit quaternions)
From: Strife Onizuka
CODE

integer SameAngle(rotation a, rotation b)
{
return llRot2Angle(a/b) < 0.000872664625997164;// 1/10th of a degree
}
Yeah. I don't recall if that ever returns a negative number, or if it might sometimes return something close to 2*PI for a small rotation, but some variant on this should work.
_____________________
-Seifert Surface
2G!tGLf 2nLt9cG
Keiki Lemieux
I make HUDDLES
Join date: 8 Jul 2005
Posts: 1,490
03-20-2006 20:14
Thank you for the ideas!
_____________________
imakehuddles.com/wordpress/
Keiki Lemieux
I make HUDDLES
Join date: 8 Jul 2005
Posts: 1,490
03-21-2006 00:09
Just a follow up, I'm trying Strife's solution, but just FYI, you would need to change it to:

CODE

integer SameAngle(rotation a, rotation b)
{
float c = llRot2Angle( a/b );
return ( c < 0.000872664625997164 || c > ( PI * 2 ) - 0.000872664625997164 ) ;// 1/10th of a degree
}


Apparently it gives the result of 6.283185 for some values for a and b.
_____________________
imakehuddles.com/wordpress/
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
03-21-2006 05:03
From: Keiki Lemieux
Just a follow up, I'm trying Strife's solution, but just FYI, you would need to change it to:

CODE

integer SameAngle(rotation a, rotation b)
{
float c = llRot2Angle( a/b );
return ( c < 0.000872664625997164 || c > ( PI * 2 ) - 0.000872664625997164 ) ;// 1/10th of a degree
}


Apparently it gives the result of 6.283185 for some values for a and b.



hmmm i was worried about that, only did some basic testing (where that didn't turn up).
CODE

integer SameAngle(rotation a, rotation b)
{
a.x = llRot2Angle( a/b );
return llFabs( a.x - (integer)(a.x / TWO_PI) ) < 0.000872664625997164;// 1/10th of a degree
}

that should take care of negitives as well as your TWO_PI multiples
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river.
- Cyril Connolly

Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence.
- James Nachtwey
Lex Neva
wears dorky glasses
Join date: 27 Nov 2004
Posts: 1,361
03-21-2006 10:08
From: Seifert Surface
(although you're doing something weird if your quaternions aren't unit quaternions)


The originally-posted quaternions weren't unit quaternions at all. I think the process of converting them to unit quaternions would make those specific quaternions equal (or as close as floating points can get), in fact. As far as I can remember, quaternions aren't "legit" unless they're unit vectors.

By the way, would llAngleBetween() help? It might return negative angles rather than 2*pi - small bits. Also, when using 2*PI in a script, you can use the pre-multiplied TWO_PI instead for that tiny bit of added speed ;)
Kalleb Underthorn
Registered User
Join date: 30 Jul 2003
Posts: 40
03-21-2006 11:22
Ok, this is a DUMB method... but...

CODE


rotation rotA = <-0.5000,-0.5000,-0.5000,-0.5000>;
rotation rotB = <0.50000,0.50000,0.50000,0.50000>;
vector vec = <1.0000,0.0000,0.0000>;

if( llVecDist( rotA * vec, rotB * vec ) < 0.001 )
{
llOwnerSay(" The angles are near identical")
}

Seifert Surface
Mathematician
Join date: 14 Jun 2005
Posts: 912
03-21-2006 11:49
From: Lex Neva
The originally-posted quaternions weren't unit quaternions at all. I think the process of converting them to unit quaternions would make those specific quaternions equal (or as close as floating points can get), in fact. As far as I can remember, quaternions aren't "legit" unless they're unit vectors.

No, they are unit. <0.5, 0.5, 0.5, 0.5> is unit because llSqrt(0.5*0.5 + 0.5*0.5 + 0.5*0.5 + 0.5*0.5) == 1. You get the same from <-0.5, -0.5, -0.5, -0.5>. To convert to a unit quaternion you divide by it's length, which won't alter either of these.
_____________________
-Seifert Surface
2G!tGLf 2nLt9cG
Lex Neva
wears dorky glasses
Join date: 27 Nov 2004
Posts: 1,361
03-22-2006 10:02
Oops. Hah. That's what I get for posting before I wake up.
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
03-22-2006 14:26
From: Kalleb Underthorn
Ok, this is a DUMB method... but...

CODE


rotation rotA = <-0.5000,-0.5000,-0.5000,-0.5000>;
rotation rotB = <0.50000,0.50000,0.50000,0.50000>;
vector vec = <1.0000,0.0000,0.0000>;

if( llVecDist( rotA * vec, rotB * vec ) < 0.001 )
{
llOwnerSay(" The angles are near identical")
}



That will only work for quaternions of the same magnitude. If you want that method to work...

CODE


rotation rotA = <-0.5000,-0.5000,-0.5000,-0.5000>;
rotation rotB = <0.50000,0.50000,0.50000,0.50000>;
vector vec = <1.0000,0.0000,0.0000>;

if( llVecDist( llVecNorm(rotA * vec), llVecNorm(rotB * vec) ) < 0.001 )
{
llOwnerSay(" The angles are near identical")
}

_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river.
- Cyril Connolly

Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence.
- James Nachtwey