<?xml version="1.0" encoding="UTF-8" standalone="yes"?><oembed><version><![CDATA[1.0]]></version><provider_name><![CDATA[The ryg blog]]></provider_name><provider_url><![CDATA[https://fgiesen.wordpress.com]]></provider_url><author_name><![CDATA[fgiesen]]></author_name><author_url><![CDATA[https://fgiesen.wordpress.com/author/fgiesen/]]></author_url><title><![CDATA[Rotating a single vector using a&nbsp;quaternion]]></title><type><![CDATA[link]]></type><html><![CDATA[<p>This is a rehash of something I wrote in a forum post something like 10 years ago. It turns out that forum prohibited archiving in its <code>robots.txt</code> so it&#8217;s not on the Internet Archive. The original operator of said forum hosted a copy (with broken formatting) of the original posts for a while, but at a different URL, breaking all links. And now that copy&#8217;s gone too, again with archiving disabled apparently. Sigh.</p>
<p>I got asked about this yesterday; I don&#8217;t have a copy of my original derivation anymore either, but here&#8217;s my best attempt at reconstructing what I probably wrote back then, and hopefully it won&#8217;t get lost again this time.</p>
<p>Suppose you&#8217;re given a unit quaternion <img src="https://s0.wp.com/latex.php?latex=q&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=q&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=q&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="q" class="latex" /> and a vector <img src="https://s0.wp.com/latex.php?latex=v&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=v&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=v&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="v" class="latex" />. Quaternions are a common rotation representation in several fields (including computer graphics and numerical rigid-body dynamics) for reasons beyond the scope of this post. To apply a rotation to a vector, one computes the quaternion product <img src="https://s0.wp.com/latex.php?latex=q+v+q%5E%2A&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=q+v+q%5E%2A&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=q+v+q%5E%2A&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="q v q^*" class="latex" />, where <img src="https://s0.wp.com/latex.php?latex=v&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=v&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=v&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="v" class="latex" /> is implicitly identified with the quaternion with real (scalar) part 0 and <img src="https://s0.wp.com/latex.php?latex=v&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=v&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=v&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="v" class="latex" /> as its imaginary part, and <img src="https://s0.wp.com/latex.php?latex=q%5E%2A&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=q%5E%2A&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=q%5E%2A&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="q^*" class="latex" /> denotes the conjugate of <img src="https://s0.wp.com/latex.php?latex=q&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=q&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=q&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="q" class="latex" />. Such quaternions with a real part of 0 are also referred to as &#8220;pure imaginary&#8221; quaternions. Anyway, the result of the above product is another pure imaginary quaternion, corresponding to the rotated vector.</p>
<p>This is all explained and motivated elsewhere, and I won&#8217;t bother doing so here. Now generally, you often want to apply the same transformation to many vectors. In that case, you&#8217;re better off turning the quaternion into the equivalent 3&#215;3 rotation matrix first. You can look up the formula elsewhere or work it out from the expression above with some algebra. That&#8217;s not the topic of this post either.</p>
<p>But sometimes you really only want to transform a single vector with a quaternion, or have other reasons for not wanting to expand to an explicit 3&#215;3 (or larger) matrix first, like for example trying to minimize live register count in a shader program. So let&#8217;s look at ways of doing that.</p>
<h3>The direct way</h3>
<p>First, I&#8217;m going to split quaternions in their real (scalar) and imaginary (vector) parts, writing <img src="https://s0.wp.com/latex.php?latex=q%3D%28q_r%2C+q_%7Bxyz%7D%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=q%3D%28q_r%2C+q_%7Bxyz%7D%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=q%3D%28q_r%2C+q_%7Bxyz%7D%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="q=(q_r, q_{xyz})" class="latex" /> where <img src="https://s0.wp.com/latex.php?latex=q_r&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=q_r&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=q_r&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="q_r" class="latex" /> is the real part and <img src="https://s0.wp.com/latex.php?latex=q_%7Bxyz%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=q_%7Bxyz%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=q_%7Bxyz%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="q_{xyz}" class="latex" /> imaginary. The conjugate of <img src="https://s0.wp.com/latex.php?latex=q&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=q&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=q&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="q" class="latex" /> is given by <img src="https://s0.wp.com/latex.php?latex=q%5E%2A%3D%28q_r%2C+-q_%7Bxyz%7D%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=q%5E%2A%3D%28q_r%2C+-q_%7Bxyz%7D%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=q%5E%2A%3D%28q_r%2C+-q_%7Bxyz%7D%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="q^*=(q_r, -q_{xyz})" class="latex" />.</p>
<p>The product of two quaternions <img src="https://s0.wp.com/latex.php?latex=a&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=a&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=a&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="a" class="latex" /> and <img src="https://s0.wp.com/latex.php?latex=b&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=b&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=b&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="b" class="latex" /> is given by</p>
<p><img src="https://s0.wp.com/latex.php?latex=ab+%3D+%28a_r+b_r+-+a_%7Bxyz%7D+%5Ccdot+b_%7Bxyz%7D%2C+a_r+b_%7Bxyz%7D+%2B+b_r+a_%7Bxyz%7D+%2B+a_%7Bxyz%7D+%5Ctimes+b_%7Bxyz%7D%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=ab+%3D+%28a_r+b_r+-+a_%7Bxyz%7D+%5Ccdot+b_%7Bxyz%7D%2C+a_r+b_%7Bxyz%7D+%2B+b_r+a_%7Bxyz%7D+%2B+a_%7Bxyz%7D+%5Ctimes+b_%7Bxyz%7D%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=ab+%3D+%28a_r+b_r+-+a_%7Bxyz%7D+%5Ccdot+b_%7Bxyz%7D%2C+a_r+b_%7Bxyz%7D+%2B+b_r+a_%7Bxyz%7D+%2B+a_%7Bxyz%7D+%5Ctimes+b_%7Bxyz%7D%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="ab = (a_r b_r - a_{xyz} &#92;cdot b_{xyz}, a_r b_{xyz} + b_r a_{xyz} + a_{xyz} &#92;times b_{xyz})" class="latex" /></p>
<p>where <img src="https://s0.wp.com/latex.php?latex=%5Ccdot&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%5Ccdot&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%5Ccdot&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="&#92;cdot" class="latex" /> denotes the usual dot product and <img src="https://s0.wp.com/latex.php?latex=%5Ctimes&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%5Ctimes&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%5Ctimes&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="&#92;times" class="latex" /> the cross product. If you&#8217;re not used to seeing this in vector notation, I recommend using this (or something more abstract like geometric algebra) for derivations; writing everything in terms of scalars and the <img src="https://s0.wp.com/latex.php?latex=i%2C+j%2C+k&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=i%2C+j%2C+k&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=i%2C+j%2C+k&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="i, j, k" class="latex" /> basis elements makes you miss the forest for the trees.</p>
<p>Anyway, armed with this formula, we can compute our final product without too much trouble. Let&#8217;s start with the <img src="https://s0.wp.com/latex.php?latex=qv&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=qv&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=qv&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="qv" class="latex" /> part:</p>
<p><img src="https://s0.wp.com/latex.php?latex=qv+%3D+%28-q_%7Bxyz%7D+%5Ccdot+v%2C+q_r+v+%2B+q_%7Bxyz%7D+%5Ctimes+v%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=qv+%3D+%28-q_%7Bxyz%7D+%5Ccdot+v%2C+q_r+v+%2B+q_%7Bxyz%7D+%5Ctimes+v%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=qv+%3D+%28-q_%7Bxyz%7D+%5Ccdot+v%2C+q_r+v+%2B+q_%7Bxyz%7D+%5Ctimes+v%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="qv = (-q_{xyz} &#92;cdot v, q_r v + q_{xyz} &#92;times v)" class="latex" /></p>
<p>Not so bad. Now we have to multiply it from the right by <img src="https://s0.wp.com/latex.php?latex=q%5E%2A&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=q%5E%2A&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=q%5E%2A&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="q^*" class="latex" />, which I&#8217;ll do in multiple steps. First, let&#8217;s take care of the real part, by multiplying our just-computed values for <img src="https://s0.wp.com/latex.php?latex=qv&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=qv&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=qv&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="qv" class="latex" /> with <img src="https://s0.wp.com/latex.php?latex=q%5E%2A&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=q%5E%2A&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=q%5E%2A&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="q^*" class="latex" /> using the general multiplication formula above:</p>
<p><img src="https://s0.wp.com/latex.php?latex=%28qvq%5E%2A%29_r+%3D+-q_r+%28q_%7Bxyz%7D+%5Ccdot+v%29+-+%28%28q_r+v+%2B+q_%7Bxyz%7D+%5Ctimes+v%29+%5Ccdot+%28-q_%7Bxyz%7D%29%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%28qvq%5E%2A%29_r+%3D+-q_r+%28q_%7Bxyz%7D+%5Ccdot+v%29+-+%28%28q_r+v+%2B+q_%7Bxyz%7D+%5Ctimes+v%29+%5Ccdot+%28-q_%7Bxyz%7D%29%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%28qvq%5E%2A%29_r+%3D+-q_r+%28q_%7Bxyz%7D+%5Ccdot+v%29+-+%28%28q_r+v+%2B+q_%7Bxyz%7D+%5Ctimes+v%29+%5Ccdot+%28-q_%7Bxyz%7D%29%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="(qvq^*)_r = -q_r (q_{xyz} &#92;cdot v) - ((q_r v + q_{xyz} &#92;times v) &#92;cdot (-q_{xyz}))" class="latex" /><br />
<img src="https://s0.wp.com/latex.php?latex=%3D+-q_r+%28q_%7Bxyz%7D+%5Ccdot+v%29+%2B+q_r+%28v+%5Ccdot+q_%7Bxyz%7D%29+%2B+%28%28q_%7Bxyz%7D+%5Ctimes+v%29+%5Ccdot+q_%7Bxyz%7D%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%3D+-q_r+%28q_%7Bxyz%7D+%5Ccdot+v%29+%2B+q_r+%28v+%5Ccdot+q_%7Bxyz%7D%29+%2B+%28%28q_%7Bxyz%7D+%5Ctimes+v%29+%5Ccdot+q_%7Bxyz%7D%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%3D+-q_r+%28q_%7Bxyz%7D+%5Ccdot+v%29+%2B+q_r+%28v+%5Ccdot+q_%7Bxyz%7D%29+%2B+%28%28q_%7Bxyz%7D+%5Ctimes+v%29+%5Ccdot+q_%7Bxyz%7D%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="= -q_r (q_{xyz} &#92;cdot v) + q_r (v &#92;cdot q_{xyz}) + ((q_{xyz} &#92;times v) &#92;cdot q_{xyz})" class="latex" /><br />
<img src="https://s0.wp.com/latex.php?latex=%3D+q_%7Bxyz%7D+%5Ccdot+%28q_%7Bxyz%7D+%5Ctimes+v%29+%3D+0&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%3D+q_%7Bxyz%7D+%5Ccdot+%28q_%7Bxyz%7D+%5Ctimes+v%29+%3D+0&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%3D+q_%7Bxyz%7D+%5Ccdot+%28q_%7Bxyz%7D+%5Ctimes+v%29+%3D+0&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="= q_{xyz} &#92;cdot (q_{xyz} &#92;times v) = 0" class="latex" /></p>
<p>because the first two dot products are identical and the cross product of <img src="https://s0.wp.com/latex.php?latex=q_%7Bxyz%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=q_%7Bxyz%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=q_%7Bxyz%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="q_{xyz}" class="latex" /> and <img src="https://s0.wp.com/latex.php?latex=v&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=v&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=v&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="v" class="latex" /> is perpendicular to <img src="https://s0.wp.com/latex.php?latex=q_%7Bxyz%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=q_%7Bxyz%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=q_%7Bxyz%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="q_{xyz}" class="latex" />. This proves that <img src="https://s0.wp.com/latex.php?latex=qvq%5E%2A&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=qvq%5E%2A&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=qvq%5E%2A&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="qvq^*" class="latex" /> is indeed a pure imaginary quaternion again, just like the <img src="https://s0.wp.com/latex.php?latex=v&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=v&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=v&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="v" class="latex" /> we started out with.</p>
<p>Nice to know, but of course we&#8217;re actually here for the vector part:</p>
<p><img src="https://s0.wp.com/latex.php?latex=%28qvq%5E%2A%29_%7Bxyz%7D+%3D+%28-q_%7Bxyz%7D+%5Ccdot+v%29+%28-q_%7Bxyz%7D%29+%2B+q_r+%28q_r+v+%2B+q_%7Bxyz%7D+%5Ctimes+v%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%28qvq%5E%2A%29_%7Bxyz%7D+%3D+%28-q_%7Bxyz%7D+%5Ccdot+v%29+%28-q_%7Bxyz%7D%29+%2B+q_r+%28q_r+v+%2B+q_%7Bxyz%7D+%5Ctimes+v%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%28qvq%5E%2A%29_%7Bxyz%7D+%3D+%28-q_%7Bxyz%7D+%5Ccdot+v%29+%28-q_%7Bxyz%7D%29+%2B+q_r+%28q_r+v+%2B+q_%7Bxyz%7D+%5Ctimes+v%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="(qvq^*)_{xyz} = (-q_{xyz} &#92;cdot v) (-q_{xyz}) + q_r (q_r v + q_{xyz} &#92;times v)" class="latex" /><br />
<img src="https://s0.wp.com/latex.php?latex=%2B+%28q_r+v+%2B+q_%7Bxyz%7D+%5Ctimes+v%29+%5Ctimes+%28-q_%7Bxyz%7D%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%2B+%28q_r+v+%2B+q_%7Bxyz%7D+%5Ctimes+v%29+%5Ctimes+%28-q_%7Bxyz%7D%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%2B+%28q_r+v+%2B+q_%7Bxyz%7D+%5Ctimes+v%29+%5Ctimes+%28-q_%7Bxyz%7D%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="+ (q_r v + q_{xyz} &#92;times v) &#92;times (-q_{xyz})" class="latex" /><br />
<img src="https://s0.wp.com/latex.php?latex=%3D+%28q_%7Bxyz%7D+%5Ccdot+v%29+q_%7Bxyz%7D+%2B+q_r%5E2+v+%2B+q_r+%28q_%7Bxyz%7D+%5Ctimes+v%29+%2B+q_%7Bxyz%7D+%5Ctimes+%28q_r+v+%2B+q_%7Bxyz%7D+%5Ctimes+v%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%3D+%28q_%7Bxyz%7D+%5Ccdot+v%29+q_%7Bxyz%7D+%2B+q_r%5E2+v+%2B+q_r+%28q_%7Bxyz%7D+%5Ctimes+v%29+%2B+q_%7Bxyz%7D+%5Ctimes+%28q_r+v+%2B+q_%7Bxyz%7D+%5Ctimes+v%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%3D+%28q_%7Bxyz%7D+%5Ccdot+v%29+q_%7Bxyz%7D+%2B+q_r%5E2+v+%2B+q_r+%28q_%7Bxyz%7D+%5Ctimes+v%29+%2B+q_%7Bxyz%7D+%5Ctimes+%28q_r+v+%2B+q_%7Bxyz%7D+%5Ctimes+v%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="= (q_{xyz} &#92;cdot v) q_{xyz} + q_r^2 v + q_r (q_{xyz} &#92;times v) + q_{xyz} &#92;times (q_r v + q_{xyz} &#92;times v)" class="latex" /><br />
<img src="https://s0.wp.com/latex.php?latex=%3D+%28q_%7Bxyz%7D+%5Ccdot+v%29+q_%7Bxyz%7D+%2B+q_r%5E2+v+%2B+2+q_r+%28q_%7Bxyz%7D+%5Ctimes+v%29+%2B+q_%7Bxyz%7D+%5Ctimes+%28q_%7Bxyz%7D+%5Ctimes+v%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%3D+%28q_%7Bxyz%7D+%5Ccdot+v%29+q_%7Bxyz%7D+%2B+q_r%5E2+v+%2B+2+q_r+%28q_%7Bxyz%7D+%5Ctimes+v%29+%2B+q_%7Bxyz%7D+%5Ctimes+%28q_%7Bxyz%7D+%5Ctimes+v%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%3D+%28q_%7Bxyz%7D+%5Ccdot+v%29+q_%7Bxyz%7D+%2B+q_r%5E2+v+%2B+2+q_r+%28q_%7Bxyz%7D+%5Ctimes+v%29+%2B+q_%7Bxyz%7D+%5Ctimes+%28q_%7Bxyz%7D+%5Ctimes+v%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="= (q_{xyz} &#92;cdot v) q_{xyz} + q_r^2 v + 2 q_r (q_{xyz} &#92;times v) + q_{xyz} &#92;times (q_{xyz} &#92;times v)" class="latex" /></p>
<p>which so far has used nothing fancier than the antisymmetry of the cross product <img src="https://s0.wp.com/latex.php?latex=a+%5Ctimes+b+%3D+-b+%5Ctimes+a&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=a+%5Ctimes+b+%3D+-b+%5Ctimes+a&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=a+%5Ctimes+b+%3D+-b+%5Ctimes+a&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="a &#92;times b = -b &#92;times a" class="latex" />.</p>
<p>If we pull out and name the shared cross product, we get</p>
<p><img src="https://s0.wp.com/latex.php?latex=u+%3D+q_%7Bxyz%7D+%5Ctimes+v&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=u+%3D+q_%7Bxyz%7D+%5Ctimes+v&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=u+%3D+q_%7Bxyz%7D+%5Ctimes+v&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="u = q_{xyz} &#92;times v" class="latex" /><br />
<img src="https://s0.wp.com/latex.php?latex=%28qvq%5E%2A%29_%7Bxyz%7D+%3D+%28q_%7Bxyz%7D+%5Ccdot+v%29+q_%7Bxyz%7D+%2B+q_r%5E2+v+%2B+2+q_r+u+%2B+q_%7Bxyz%7D+%5Ctimes+u&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%28qvq%5E%2A%29_%7Bxyz%7D+%3D+%28q_%7Bxyz%7D+%5Ccdot+v%29+q_%7Bxyz%7D+%2B+q_r%5E2+v+%2B+2+q_r+u+%2B+q_%7Bxyz%7D+%5Ctimes+u&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%28qvq%5E%2A%29_%7Bxyz%7D+%3D+%28q_%7Bxyz%7D+%5Ccdot+v%29+q_%7Bxyz%7D+%2B+q_r%5E2+v+%2B+2+q_r+u+%2B+q_%7Bxyz%7D+%5Ctimes+u&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="(qvq^*)_{xyz} = (q_{xyz} &#92;cdot v) q_{xyz} + q_r^2 v + 2 q_r u + q_{xyz} &#92;times u" class="latex" /></p>
<p>which is the direct expression for the transformed vector from the formula. This is what you get if you just plug everything into the formulas and apply basic algebraic simplifications until you run out of obvious things to try (which is exactly what we did).</p>
<p>In terms of scalar operation count, this boils down to two cross products at 6 multiplies and 3 additions (well, subtractions) each; one 3D dot product at 3 multiplies and 2 additions; 3 vector-by-scalar multiplications at 3 multiplies each; two scalar multiplies (to form <img src="https://s0.wp.com/latex.php?latex=q_r%5E2&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=q_r%5E2&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=q_r%5E2&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="q_r^2" class="latex" /> and <img src="https://s0.wp.com/latex.php?latex=2q_r&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=2q_r&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=2q_r&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="2q_r" class="latex" />, although the latter can also be computed via addition if you prefer); and finally 3 vector additions at 3 adds each. The total operation count is thus 26 scalar multiplies and 17 additions, unless I miscounted. For GPUs, a multiply-add &#8220;a*b+c&#8221; generally counts as a single operation, and in that case the scalar operation count is 9 scalar multiplies and 17 scalar multiply-adds.</p>
<h3>Stand back, I&#8217;m going to try algebra!</h3>
<p>We can do better than that. So far, we haven&#8217;t used that <img src="https://s0.wp.com/latex.php?latex=q&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=q&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=q&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="q" class="latex" /> is a unit quaternion, meaning that <img src="https://s0.wp.com/latex.php?latex=q_r%5E2+%2B+q_%7Bxyz%7D+%5Ccdot+q_%7Bxyz%7D+%3D+1&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=q_r%5E2+%2B+q_%7Bxyz%7D+%5Ccdot+q_%7Bxyz%7D+%3D+1&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=q_r%5E2+%2B+q_%7Bxyz%7D+%5Ccdot+q_%7Bxyz%7D+%3D+1&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="q_r^2 + q_{xyz} &#92;cdot q_{xyz} = 1" class="latex" />. We can thus plug in <img src="https://s0.wp.com/latex.php?latex=%281+-+q_%7Bxyz%7D+%5Ccdot+q_%7Bxyz%7D%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%281+-+q_%7Bxyz%7D+%5Ccdot+q_%7Bxyz%7D%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%281+-+q_%7Bxyz%7D+%5Ccdot+q_%7Bxyz%7D%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="(1 - q_{xyz} &#92;cdot q_{xyz})" class="latex" /> for <img src="https://s0.wp.com/latex.php?latex=q_r%5E2&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=q_r%5E2&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=q_r%5E2&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="q_r^2" class="latex" />, which yields:</p>
<p><img src="https://s0.wp.com/latex.php?latex=%28qvq%5E%2A%29_%7Bxyz%7D+%3D+%28q_%7Bxyz%7D+%5Ccdot+v%29+q_%7Bxyz%7D+%2B+%281+-+q_%7Bxyz%7D+%5Ccdot+q_%7Bxyz%7D%29+v+%2B+2+q_r+u+%2B+q_%7Bxyz%7D+%5Ctimes+u&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%28qvq%5E%2A%29_%7Bxyz%7D+%3D+%28q_%7Bxyz%7D+%5Ccdot+v%29+q_%7Bxyz%7D+%2B+%281+-+q_%7Bxyz%7D+%5Ccdot+q_%7Bxyz%7D%29+v+%2B+2+q_r+u+%2B+q_%7Bxyz%7D+%5Ctimes+u&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%28qvq%5E%2A%29_%7Bxyz%7D+%3D+%28q_%7Bxyz%7D+%5Ccdot+v%29+q_%7Bxyz%7D+%2B+%281+-+q_%7Bxyz%7D+%5Ccdot+q_%7Bxyz%7D%29+v+%2B+2+q_r+u+%2B+q_%7Bxyz%7D+%5Ctimes+u&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="(qvq^*)_{xyz} = (q_{xyz} &#92;cdot v) q_{xyz} + (1 - q_{xyz} &#92;cdot q_{xyz}) v + 2 q_r u + q_{xyz} &#92;times u" class="latex" /><br />
<img src="https://s0.wp.com/latex.php?latex=%3D+v+%2B+%28q_%7Bxyz%7D+%5Ccdot+v%29+q_%7Bxyz%7D+-+%28q_%7Bxyz%7D+%5Ccdot+q_%7Bxyz%7D%29+v+%2B+2+q_r+u+%2B+q_%7Bxyz%7D+%5Ctimes+u&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%3D+v+%2B+%28q_%7Bxyz%7D+%5Ccdot+v%29+q_%7Bxyz%7D+-+%28q_%7Bxyz%7D+%5Ccdot+q_%7Bxyz%7D%29+v+%2B+2+q_r+u+%2B+q_%7Bxyz%7D+%5Ctimes+u&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%3D+v+%2B+%28q_%7Bxyz%7D+%5Ccdot+v%29+q_%7Bxyz%7D+-+%28q_%7Bxyz%7D+%5Ccdot+q_%7Bxyz%7D%29+v+%2B+2+q_r+u+%2B+q_%7Bxyz%7D+%5Ctimes+u&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="= v + (q_{xyz} &#92;cdot v) q_{xyz} - (q_{xyz} &#92;cdot q_{xyz}) v + 2 q_r u + q_{xyz} &#92;times u" class="latex" /></p>
<p>This might look worse, but it&#8217;s progress, because we can now apply the <a href="https://en.wikipedia.org/wiki/Triple_product#Vector_triple_product">vector triple product</a> identity</p>
<p><img src="https://s0.wp.com/latex.php?latex=a+%5Ctimes+%28b+%5Ctimes+c%29+%3D+%28a+%5Ccdot+c%29b+-+%28a+%5Ccdot+b%29c&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=a+%5Ctimes+%28b+%5Ctimes+c%29+%3D+%28a+%5Ccdot+c%29b+-+%28a+%5Ccdot+b%29c&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=a+%5Ctimes+%28b+%5Ctimes+c%29+%3D+%28a+%5Ccdot+c%29b+-+%28a+%5Ccdot+b%29c&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="a &#92;times (b &#92;times c) = (a &#92;cdot c)b - (a &#92;cdot b)c" class="latex" /></p>
<p>with <img src="https://s0.wp.com/latex.php?latex=a%3Dq_%7Bxyz%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=a%3Dq_%7Bxyz%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=a%3Dq_%7Bxyz%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="a=q_{xyz}" class="latex" />, <img src="https://s0.wp.com/latex.php?latex=b%3Dq_%7Bxyz%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=b%3Dq_%7Bxyz%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=b%3Dq_%7Bxyz%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="b=q_{xyz}" class="latex" />, <img src="https://s0.wp.com/latex.php?latex=c%3Dv&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=c%3Dv&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=c%3Dv&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="c=v" class="latex" />, leaving us with:</p>
<p><img src="https://s0.wp.com/latex.php?latex=%28qvq%5E%2A%29_%7Bxyz%7D+%3D+v+%2B+q_%7Bxyz%7D+%5Ctimes+%28q_%7Bxyz%7D+%5Ctimes+v%29+%2B+2+q_r+u+%2B+q_%7Bxyz%7D+%5Ctimes+u&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%28qvq%5E%2A%29_%7Bxyz%7D+%3D+v+%2B+q_%7Bxyz%7D+%5Ctimes+%28q_%7Bxyz%7D+%5Ctimes+v%29+%2B+2+q_r+u+%2B+q_%7Bxyz%7D+%5Ctimes+u&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%28qvq%5E%2A%29_%7Bxyz%7D+%3D+v+%2B+q_%7Bxyz%7D+%5Ctimes+%28q_%7Bxyz%7D+%5Ctimes+v%29+%2B+2+q_r+u+%2B+q_%7Bxyz%7D+%5Ctimes+u&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="(qvq^*)_{xyz} = v + q_{xyz} &#92;times (q_{xyz} &#92;times v) + 2 q_r u + q_{xyz} &#92;times u" class="latex" /><br />
<img src="https://s0.wp.com/latex.php?latex=%3D+v+%2B+q_%7Bxyz%7D+%5Ctimes+u+%2B+2+q_r+u+%2B+q_%7Bxyz%7D+%5Ctimes+u&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%3D+v+%2B+q_%7Bxyz%7D+%5Ctimes+u+%2B+2+q_r+u+%2B+q_%7Bxyz%7D+%5Ctimes+u&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%3D+v+%2B+q_%7Bxyz%7D+%5Ctimes+u+%2B+2+q_r+u+%2B+q_%7Bxyz%7D+%5Ctimes+u&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="= v + q_{xyz} &#92;times u + 2 q_r u + q_{xyz} &#92;times u" class="latex" /><br />
<img src="https://s0.wp.com/latex.php?latex=%3D+v+%2B+2+q_r+u+%2B+2+q_%7Bxyz%7D+%5Ctimes+u&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%3D+v+%2B+2+q_r+u+%2B+2+q_%7Bxyz%7D+%5Ctimes+u&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%3D+v+%2B+2+q_r+u+%2B+2+q_%7Bxyz%7D+%5Ctimes+u&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="= v + 2 q_r u + 2 q_{xyz} &#92;times u" class="latex" /></p>
<p>The two remaining terms involving <img src="https://s0.wp.com/latex.php?latex=u&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=u&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=u&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="u" class="latex" /> both multiply by two, so we use a slightly different shared temporary for the final version of our formula:</p>
<p><img src="https://s0.wp.com/latex.php?latex=t+%3D+2+q_%7Bxyz%7D+%5Ctimes+v&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=t+%3D+2+q_%7Bxyz%7D+%5Ctimes+v&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=t+%3D+2+q_%7Bxyz%7D+%5Ctimes+v&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="t = 2 q_{xyz} &#92;times v" class="latex" /><br />
<img src="https://s0.wp.com/latex.php?latex=%28qvq%5E%2A%29_%7Bxyz%7D+%3D+v+%2B+q_r+t+%2B+q_%7Bxyz%7D+%5Ctimes+t&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%28qvq%5E%2A%29_%7Bxyz%7D+%3D+v+%2B+q_r+t+%2B+q_%7Bxyz%7D+%5Ctimes+t&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%28qvq%5E%2A%29_%7Bxyz%7D+%3D+v+%2B+q_r+t+%2B+q_%7Bxyz%7D+%5Ctimes+t&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="(qvq^*)_{xyz} = v + q_r t + q_{xyz} &#92;times t" class="latex" /></p>
<p>Final scalar operation count: without multiply-adds, the two cross products sum to 12 multiplies and 6 adds, scaling t by two takes 3 multiplies (or adds, your choice), and the final vector-by-scalar multiply and summation take 3 multiplies and 6 adds, respectively. That&#8217;s 18 multiplies and 12 adds total, or 15 multiplies and 15 adds if you did the doubling using addition.</p>
<p>Either way, that&#8217;s a significant reduction on both counts.</p>
<p>With multiply-adds, I count a total of 3 multiplies and 9 multiply-adds for the cross products (the first cross product has nothing to sum to, but the second does); either 3 multiplies or 3 adds (your choice again) for the doubling; and another 3 multiply-adds for the <img src="https://s0.wp.com/latex.php?latex=v+%2B+q_r+t&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=v+%2B+q_r+t&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=v+%2B+q_r+t&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="v + q_r t" class="latex" /> portion. That&#8217;s either 6 multiplies and 12 multiply-adds or 3 multiplies, 3 adds and 12 multiply-adds. Furthermore some GPUs can fold a doubling straight into the operand without counting as another operation at all; in that case we get 3 multiplies and 12 multiply-adds.</p>
<p>For comparison, multiplying a vector by a 3&#215;3 rotation matrix takes 9 multiplies and 6 additions (or 3 multiplies plus 6 multiply-adds). So even though this is much better than we started out with, it&#8217;s generally still worthwhile to form that rotation matrix explicitly if you plan on transforming lots of vectors by the same quaternion, and aren&#8217;t worried about GPU vector register counts or similar.</p>
]]></html></oembed>