Jump to content

[Math] Quaternion to Euler function


malu05
 Share

Recommended Posts

Im trying to make a function that can convert Quaternions to Euler and Euler to Quaternions.

A bit like http://www.onlineconversion.com/quaternions.htm but just with the reverse function aswell.

I tried using the wikipeida entry for it but since my understanding of highlevel math is kinda limited my formula

$X = cos($yaw/2) * sin($pitch/2) * cos($roll/2) + sin($yaw/2) * cos($pitch/2) * sin($roll/2)

$Y = sin($yaw/2) * cos($pitch/2) * cos($roll/2) - cos($yaw/2) * sin($pitch/2) * sin($roll/2)

$Z = cos($yaw/2) * cos($pitch/2) * sin($roll/2) - sin($yaw/2) * sin($pitch/2) * cos($roll/2)

$W = cos($yaw/2) * cos($pitch/2) * cos($roll/2) + sin($yaw/2) * sin($pitch/2) * sin($roll/2)

turned out incorrect.

Can anyone guide my towards something?

[center][u]WoW Machinima Tool[/u] (Tool for Machinima Artists) [/center]

Link to comment
Share on other sites

Here a direct conversion of the javascript used in that sites calculator, minus the parameter checking. Now it just has to be reversed.

#AutoIt3Wrapper_Au3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7
#NoTrayIcon

Global $Pi = 4 * ATan(1)

Global $e1 = 30
Global $e2 = 60
Global $e3 = 90

Global $u0 = Sqrt(Cos($e2 * $Pi / 180) * Cos($e1 * $Pi / 180) + Cos($e2 * $Pi / 180) * Cos($e3 * $Pi / 180) - Sin($e2 * $Pi / 180) * Sin($e1 * $Pi / 180) * Sin($e3 * $Pi / 180) + Cos($e1 * $Pi / 180) * Cos($e3 * $Pi / 180) + 1) / 2;
Global $u1 = (Cos($e1 * $Pi / 180) * Sin($e3 * $Pi / 180) + Cos($e2 * $Pi / 180) * Sin($e3 * $Pi / 180) + Sin($e2 * $Pi / 180) * Sin($e1 * $Pi / 180) * Cos($e3 * $Pi / 180)) / Sqrt(Cos($e2 * $Pi / 180) * Cos($e1 * $Pi / 180) + Cos($e2 * $Pi / 180) * Cos($e3 * $Pi / 180) - Sin($e2 * $Pi / 180) * Sin($e1 * $Pi / 180) * Sin($e3 * $Pi / 180) + Cos($e1 * $Pi / 180) * Cos($e3 * $Pi / 180) + 1) / 2
Global $u2 = (Sin($e2 * $Pi / 180) * Sin($e3 * $Pi / 180) - Cos($e2 * $Pi / 180) * Sin($e1 * $Pi / 180) * Cos($e3 * $Pi / 180) - Sin($e1 * $Pi / 180)) / Sqrt(Cos($e2 * $Pi / 180) * Cos($e1 * $Pi / 180) + Cos($e2 * $Pi / 180) * Cos($e3 * $Pi / 180) - Sin($e2 * $Pi / 180) * Sin($e1 * $Pi / 180) * Sin($e3 * $Pi / 180) + Cos($e1 * $Pi / 180) * Cos($e3 * $Pi / 180) + 1) / 2
Global $u3 = (Sin($e2 * $Pi / 180) * Cos($e1 * $Pi / 180) + Sin($e2 * $Pi / 180) * Cos($e3 * $Pi / 180) + Cos($e2 * $Pi / 180) * Sin($e1 * $Pi / 180) * Sin($e3 * $Pi / 180)) / Sqrt(Cos($e2 * $Pi / 180) * Cos($e1 * $Pi / 180) + Cos($e2 * $Pi / 180) * Cos($e3 * $Pi / 180) - Sin($e2 * $Pi / 180) * Sin($e1 * $Pi / 180) * Sin($e3 * $Pi / 180) + Cos($e1 * $Pi / 180) * Cos($e3 * $Pi / 180) + 1) / 2

ConsoleWrite($u0 & @CRLF)
ConsoleWrite($u1 & @CRLF)
ConsoleWrite($u2 & @CRLF)
ConsoleWrite($u3 & @CRLF)
nice thanks alot!.

Found this one aswell:

$s1 = sin($heading/2);
    $c2 = cos($attitude/2);
    $s2 = sin($attitude/2);
    $c3 = cos($bank/2);
    $s3 = sin($bank/2);
    $c1c2 = $c1*$c2;
    $s1s2 = $s1*$s2;
    $w =$c1c2*$c3 - $s1s2*$s3;
      $x =$c1c2*$s3 + $s1s2*$c3;
    $y =$s1*$c2*$c3 + $c1*$s2*$s3;
    $z =$c1*$s2*$c3 - $s1*$c2*$s3;

(its for radians)

Can anyone help me reverse it?

Edited by malu05

[center][u]WoW Machinima Tool[/u] (Tool for Machinima Artists) [/center]

Link to comment
Share on other sites

I found this one, which is C++

http://www.gamedev.net/topic/166424-quat...o-euler/page__view__findpost__

But it doesnt seem to work correctly.

$quat_x = 0.707106780551956
    $quat_y = 0
    $quat_z = 0
    $quat_w = 0.707106781821139
    $sqw = $quat_w * $quat_w;
    $sqx = $quat_x * $quat_x;
    $sqy = $quat_y * $quat_y;
    $sqz = $quat_z * $quat_z;
  
    $rotxrad = _atan2(2.0 * ( $quat_y * $quat_z + $quat_x * $quat_w ) , ( -$sqx - $sqy + $sqz + $sqw ));
    $rotyrad = asin(-2.0 * ( $quat_x * $quat_z - $quat_y * $quat_w ));
    $rotzrad = _atan2(2.0 * ( $quat_x * $quat_y + $quat_z * $quat_w ) , (  $sqx - $sqy - $sqz + $sqw ));
  
ConsoleWrite($rotxrad*$radToDeg &@crlf &$rotyrad*$radToDeg &@crlf &$rotzrad*$radToDeg)

it should return 0,0,90 but returns -89.9, 0, -0

[center][u]WoW Machinima Tool[/u] (Tool for Machinima Artists) [/center]

Link to comment
Share on other sites

The drama with Euler angles is that they make it sooo complex to rotate a body in 3D. Quaternions are way more fiendly and aren't subject to gimble lock (ask M23!).

Good luck with Euler angles!

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

Okay, in order to reverse the calculations, we have to convert this image to AutoIt code.

Posted Image

Here's my new code. The Quaternions to Euler conversion doesn't work right.

#AutoIt3Wrapper_Au3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7
#NoTrayIcon

Global $Pi = 4 * ATan(1)

; Convert Euler to Quaternions

Global $e1 = 30
Global $e2 = 60
Global $e3 = 90

Global $q0 = Sqrt(Cos($e2 * $Pi / 180) * Cos($e1 * $Pi / 180) + Cos($e2 * $Pi / 180) * Cos($e3 * $Pi / 180) - Sin($e2 * $Pi / 180) * Sin($e1 * $Pi / 180) * Sin($e3 * $Pi / 180) + Cos($e1 * $Pi / 180) * Cos($e3 * $Pi / 180) + 1) / 2
Global $q1 = (Cos($e1 * $Pi / 180) * Sin($e3 * $Pi / 180) + Cos($e2 * $Pi / 180) * Sin($e3 * $Pi / 180) + Sin($e2 * $Pi / 180) * Sin($e1 * $Pi / 180) * Cos($e3 * $Pi / 180)) / Sqrt(Cos($e2 * $Pi / 180) * Cos($e1 * $Pi / 180) + Cos($e2 * $Pi / 180) * Cos($e3 * $Pi / 180) - Sin($e2 * $Pi / 180) * Sin($e1 * $Pi / 180) * Sin($e3 * $Pi / 180) + Cos($e1 * $Pi / 180) * Cos($e3 * $Pi / 180) + 1) / 2
Global $q2 = (Sin($e2 * $Pi / 180) * Sin($e3 * $Pi / 180) - Cos($e2 * $Pi / 180) * Sin($e1 * $Pi / 180) * Cos($e3 * $Pi / 180) - Sin($e1 * $Pi / 180)) / Sqrt(Cos($e2 * $Pi / 180) * Cos($e1 * $Pi / 180) + Cos($e2 * $Pi / 180) * Cos($e3 * $Pi / 180) - Sin($e2 * $Pi / 180) * Sin($e1 * $Pi / 180) * Sin($e3 * $Pi / 180) + Cos($e1 * $Pi / 180) * Cos($e3 * $Pi / 180) + 1) / 2
Global $q3 = (Sin($e2 * $Pi / 180) * Cos($e1 * $Pi / 180) + Sin($e2 * $Pi / 180) * Cos($e3 * $Pi / 180) + Cos($e2 * $Pi / 180) * Sin($e1 * $Pi / 180) * Sin($e3 * $Pi / 180)) / Sqrt(Cos($e2 * $Pi / 180) * Cos($e1 * $Pi / 180) + Cos($e2 * $Pi / 180) * Cos($e3 * $Pi / 180) - Sin($e2 * $Pi / 180) * Sin($e1 * $Pi / 180) * Sin($e3 * $Pi / 180) + Cos($e1 * $Pi / 180) * Cos($e3 * $Pi / 180) + 1) / 2

ConsoleWrite("+> $q0 = " & $q0 & @CRLF) ; 0.5
ConsoleWrite("+> $q1 = " & $q1 & @CRLF) ; 0.683012701892219
ConsoleWrite("+> $q2 = " & $q2 & @CRLF) ; 0.183012701892219
ConsoleWrite("+> $q3 = " & $q3 & @CRLF) ; 0.5

; Quaternions to Euler

$e1 = _ATan2(2 * ($q0 * $q1 + $q2 * $q3), 1 - 2 * ($q1 ^ 2 + $q2 ^ 2))
$e2 = ASin(2 * ($q0 * $q2 - $q3 * $q1))
$e3 = _ATan2(2 * ($q0 * $q3 + $q1 * $q2), 1 - 2 * ($q2 ^ 2 + $q3 ^ 2))

ConsoleWrite("!> $e1 = " & $e1 & @CRLF) ; 30
ConsoleWrite("!> $e2 = " & $e2 & @CRLF) ; 60
ConsoleWrite("!> $e3 = " & $e3 & @CRLF) ; 90

Func _ATan2($y, $x)
    Return (2 * ATan($y / ($x + Sqrt($x ^ 2 + $y ^ 2))))
EndFunc
hmmm yea... there is something wrong there.

ConsoleWrite("!> $e1 = " & -($e1*$radToDeg) & @CRLF) ; 30

ConsoleWrite("!> $e2 = " & $e2*$radToDeg & @CRLF) ; 60

ConsoleWrite("!> $e3 = " & -($e3*$radToDeg) & @CRLF) ; 90

does a great job of on some of them but there is a 1 to 2 error on some of them

[center][u]WoW Machinima Tool[/u] (Tool for Machinima Artists) [/center]

Link to comment
Share on other sites

The drama with Euler angles is that they make it sooo complex to rotate a body in 3D. Quaternions are way more fiendly and aren't subject to gimble lock (ask M23!).

Good luck with Euler angles!

well the thing is i don't quite understand them.

I need them to rotate a camera. But say i want to rotate the camera left... in Euler i would just increment the Yaw. What would i do with Quaternions?

[center][u]WoW Machinima Tool[/u] (Tool for Machinima Artists) [/center]

Link to comment
Share on other sites

You'd rather google around to find a good Euler angles vs quaternions exposure. There is a full load of good articles on this subject.

Familiarize yourself with that material and soon Euler will hide in a very sharp angle in your mind!

Note that Euler is still a very impportant mathematician, but his so-called angles are a pain in the ass.

I need to leave right now, sorry.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

Ok.

I needed to redo the

Okay, I missed that I need to convert from radians to degrees. Here's that C++ code that returns the values you're expecting. The most confusing part about this is that I don't know which parameter is which.

Global $quat_x = 0 Global $quat_y = 0 Global $quat_z = 0.707106780551956 Global $quat_w = 0.707106781821139 Global $sqw = $quat_w ^ 2 Global $sqx = $quat_x ^ 2 Global $sqy = $quat_y ^ 2 Global $sqz = $quat_z ^ 2 Global $rotxrad = _ATan2(2.0 * ($quat_y * $quat_z + $quat_x * $quat_w), (-$sqx - $sqy + $sqz + $sqw)) Global $rotyrad = ASin(-2.0 * ($quat_x * $quat_z - $quat_y * $quat_w)) Global $rotzrad = _ATan2(2.0 * ($quat_x * $quat_y + $quat_z * $quat_w), ($sqx - $sqy - $sqz + $sqw)) ConsoleWrite(_RadToDegrees($rotxrad) & @CRLF & _RadToDegrees($rotyrad) & @CRLF & _RadToDegrees($rotzrad) & @CRLF) Func _ATan2($y, $x) Return (2 * ATan($y / ($x + Sqrt($x ^ 2 + $y ^ 2)))) EndFunc Func _RadToDegrees($i_Rads) Return $i_Rads * 57.2957795130823 EndFunc
Thanks alot, thought i needed to redo it all to make it work with non-normalized quants.

Now i just need to figure a way to keep my object/camera horizontal.

[center][u]WoW Machinima Tool[/u] (Tool for Machinima Artists) [/center]

Link to comment
Share on other sites

Ok, solved. This makes the camera rotate horizontally around its own axis.

$_ReturnEuler = Quaternion2Euler($_CurrentRotationX,$_CurrentRotationY,$_CurrentRotationZ,$_CurrentRotationW)  
$_ReturnHorizontal = SphericalRotation($_ReturnEuler[2],$_Altitude)
$_ReturnQuat= Euler2Quaternion(270+$_ReturnHorizontal[1],0+$_ReturnHorizontal[0],$_ReturnEuler[2]+$_rotationDelta)

Thanks for the help!

[center][u]WoW Machinima Tool[/u] (Tool for Machinima Artists) [/center]

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...