## RE: [Algorithms] Fastest way to rotate a vector by a quaternion in a shader

 RE: [Algorithms] Fastest way to rotate a vector by a quaternion in a shader From: Jarkko Lempiainen - 2005-04-29 19:17:15 ```I did basically the same but went to the final formula by: q=3D[qv, w] v'=3D2((qv.v)qv - (qv.qv)v + w(qv x v)) + v by using the triple product again: :(a.c)b - (a.b)c =3D a x (b x c), a=3Db=3Dqv, c=3Dv v'=3D2(qv x (qv x v) + w(qv x v))+v :a x b + a x c =3D a x (b + c) v'=3D2(qv x (qv x v) + (qv x wv))+v v'=3D2(qv x (qv x v + wv)) + v Was a good way to refresh the dusted vector math part of my brain again = ;) Jarkko -----Original Message----- From: gdalgorithms-list-admin@... = [mailto:gdalgorithms-list-admin@...] On Behalf Of = Newport, Matthew Sent: April 29, 2005 2:47 PM To: gdalgorithms-list@... Subject: RE: [Algorithms] Fastest way to rotate a vector by a quaternion = in a shader Ok, knowing what the final result was supposed to be I managed to derive = it from my original expression. Funny how much easier it is when you = know what you're supposed to end up with :-) Here's the derivation for anyone who's interested: Multiplication of two quaternions: Qr =3D Q1.Q2 =3D ( w1.w2 - v1.v2, w1.v2 + w2.v1 + v1 x v2 ) where v1 =3D (x,y,z) of Q1 w1 =3D (w) of Q1 v2 =3D (x,y,z) of Q2 w2 =3D (w) of Q2 and both . and x are the standard vector dot and cross products. Rotate a vector by a quaternion: v' =3D q.v.q* I'd already expanded this through to get: v' =3D (s.v)s + w(wv + s x v) + s x (wv + s x v) Where s is the vector part of the quaternion and w is the scalar part (q = =3D (w, s)) Expanding this out further gives: v' =3D (s.v)s + (w^2)v + 2w(s x v) + s x (s x v) The cunning trick which I hadn't spotted before is then to use the = vector triple product identity: a x (b x c) =3D b(a.c) - c(a.b) To give v' + s(s.v) - v(s.s) =3D (s.v)s + (w^2)v + 2w(s x v) + 2(s x (s x v)) Cancelling to: v' =3D (w^2 + s.s)v + 2(s x (s x v + wv)) From the definition of a quaternion representing a rotation, w =3D = cos(a/2), s =3D sin(a/2)*r where r is a unit vector representing the = axis of the rotation. So (w^2 + s.s) =3D (cos(a/2))^2 + (sin(a/2))^2 =3D = 1, giving us the final formula: v' =3D v + 2(s x (s x v + vw)) Neat :-) Thanks, Matt. -----Original Message----- From: gdalgorithms-list-admin@... = [mailto:gdalgorithms-list-admin@...] On Behalf Of = Newport, Matthew Sent: Friday, April 29, 2005 11:12 AM To: gdalgorithms-list@... Subject: RE: [Algorithms] Fastest way to rotate a vector by a quaternion = in a shader Cool, that works if I change the - Q.w * x to + Q.w * x. Now I just have = to try and figure out how it works :-) Thanks a lot, I was beginning to think it wasn't possible to get it down = to 6 instructions after playing around with it for quite a while = yesterday.=20 Matt. -----Original Message----- From: gdalgorithms-list-admin@... = [mailto:gdalgorithms-list-admin@...] On Behalf Of = Christian Sch=FCler Sent: Friday, April 29, 2005 2:16 AM To: gdalgorithms-list@... Subject: RE: [Algorithms] Fastest way to rotate a vector by a quaternion = in a shader off the top of my head, try this x' =3D x + 2 * cross( Q.xyz, cross( Q.xyz, x ) - Q.w * x ) if it doesnt work, try changing - with + or reverse the cross prod = arguments. -----Original Message----- From: gdalgorithms-list-admin@... = [mailto:gdalgorithms-list-admin@...] On Behalf Of = Newport, Matthew Sent: Thursday, April 28, 2005 11:59 PM To: gdalgorithms-list@... Subject: [Algorithms] Fastest way to rotate a vector by a quaternion in = a shader Looking through the list archives I came across this snippet from Jarkko = Lempiainen regarding rotating a vector by a quaternion in a shader: "Yeah, last time I checked rotating a vector with a quaternion was total = of 6 instructions, which is the same as your 2*cross-prod + 2 mads I = guess" I've been playing around with the definitions for quaternion = multiplication and rotating a vector by a quaternion and the best I've = been able to do is 8 instructions. Can anyone enlighten me on how it's = done in 6? Bonus points for a derivation I can follow :-) This was my = best effort: Multiplication of two quaternions: Qr =3D Q1.Q2 =3D ( w1.w2 - v1.v2, w1.v2 + w2.v1 + v1 x v2 ) where v1 =3D (x,y,z) of Q1 w1 =3D (w) of Q1 v2 =3D (x,y,z) of Q2 w2 =3D (w) of Q2 and both . and x are the standard vector dot and cross products. Rotate a vector by a quaternion: v' =3D q.v.q* Expanding this out and simplifying as best I could I got this down to = the following hlsl: float3 RotateVectorByQuaternion(float3 v, float4 q) { float3 vq =3D q.xyz; float3 vqcrossv =3D cross(vq, v); float3 wvplusvqcrossv =3D q.w * v + vqcrossv; float3 vqcrosswvplusvqcrossv =3D cross(vq, wvplusvqcrossv); float3 res =3D q.w * wvplusvqcrossv + vqcrosswvplusvqcrossv; res =3D dot(vq, v) * vq + res; return res; } Which works out to 8 clocks (2 cross products =3D 4 clocks, 1 dot = product, 3 mads). What's the secret of getting this down to 6? Thanks, Matt. ------------------------------------------------------- SF.Net email is sponsored by: Tell us your software development plans! = Take this survey and enter to win a one-year sub to SourceForge.net Plus = IDC's 2005 look-ahead and a copy of this survey Click here to start! = http://www.idcswdc.com/cgi-bin/survey?id=105hix _______________________________________________ GDAlgorithms-list mailing list GDAlgorithms-list@... https://lists.sourceforge.net/lists/listinfo/gdalgorithms-list Archives: http://sourceforge.net/mailarchive/forum.php?forum_ida88 ------------------------------------------------------- SF.Net email is sponsored by: Tell us your software development plans! Take this survey and enter to win a one-year sub to SourceForge.net Plus = IDC's 2005 look-ahead and a copy of this survey Click here to start! = http://www.idcswdc.com/cgi-bin/survey?id=105hix _______________________________________________ GDAlgorithms-list mailing list GDAlgorithms-list@... https://lists.sourceforge.net/lists/listinfo/gdalgorithms-list Archives: http://sourceforge.net/mailarchive/forum.php?forum_ida88 ------------------------------------------------------- This SF.Net email is sponsored by: NEC IT Guy Games. Get your fingers limbered up and give it your best shot. 4 great events, = 4 opportunities to win big! Highest score wins.NEC IT Guy Games. Play to = win an NEC 61 plasma display. Visit http://www.necitguy.com/?r = _______________________________________________ GDAlgorithms-list mailing list GDAlgorithms-list@... https://lists.sourceforge.net/lists/listinfo/gdalgorithms-list Archives: http://sourceforge.net/mailarchive/forum.php?forum_ida88 ------------------------------------------------------- This SF.Net email is sponsored by: NEC IT Guy Games. Get your fingers limbered up and give it your best shot. 4 great events, = 4 opportunities to win big! Highest score wins.NEC IT Guy Games. Play to = win an NEC 61 plasma display. Visit http://www.necitguy.com/?r = _______________________________________________ GDAlgorithms-list mailing list GDAlgorithms-list@... https://lists.sourceforge.net/lists/listinfo/gdalgorithms-list Archives: http://sourceforge.net/mailarchive/forum.php?forum_ida88 ```