You are right about the fact that [math]\mathbf{i}^2=\mathbf{j}^2=\mathbf{k}^2=-1[/math] as is stated in the section titled Quaternions.

Maybe if I write the product rule like this:

[math]\begin{array}{rcl}q_a & = & [s_a,\mathbf{a}] \\ q_b & = & [s_b,\mathbf{b}] \\ q_{a}q_{b} & = & [s_{a},\mathbf{a}][s_{b},\mathbf{b}] \\ & = & (s_{a}+x_{a}i+y_{a}j+z_{a}k)(s_{b}+x_{b}i+y_{b}j+z_{b}k) \\ & = & (s_{a}s_{b} + x_{a}x_{b}i^{2} + y_{a}y_{b}j^{2} + z_{a}z_{b}k^{2}) \\ & & +(s_{a}x_{b}+s_{b}x{a}+y_{a}z_{b}-y_{b}z_{a})i \\ & & +(s_{a}y_{b}+s_{b}y_{a}+z_{a}x_{b}-z_{b}x_{a})j \\ & & +(s_{a}z_{b}+s_{b}z_{a}+x_{a}y_{b}-x_{b}y_{a})k\end{array}[/math]

And we can write the dot product of the vector parts of the two quaternions as:

[math]\begin{array}{rcl}\mathbf{a}\cdot\mathbf{b} & = & x_{a}x_{b}\mathbf{i}^{2}+y_{a}y_{b}\mathbf{j}^2+z_{a}z_{b}\mathbf{k}^{2} \\ & = & (-1)x_{a}x_{b} + (-1)y_{a}y_{b} + (-1)z_{a}z_{b} \\ & = & -(x_{a}x_{b} + y_{a}y_{b} + z_{a}z_{b})\end{array}[/math]

Which we can substitute back into the original equation:

[math]\begin{array}{rcl}[s_{a},\mathbf{a}][s_{b},\mathbf{b}] & = & (s_{a}s_{b}-\mathbf{a}\cdot\mathbf{b}) \\ & & +(s_{a}x_{b}+s_{b}x{a}+y_{a}z_{b}-y_{b}z_{a})i \\ & & +(s_{a}y_{b}+s_{b}y_{a}+z_{a}x_{b}-z_{b}x_{a})j \\ & & +(s_{a}z_{b}+s_{b}z_{a}+x_{a}y_{b}-x_{b}y_{a})k\end{array}[/math]

So we are not adding any extra negatives, we are just factoring out the [math]\mathbf{i}^2=\mathbf{j}^2=\mathbf{k}^2=-1[/math] from the dot-product to get the real part of the quaternion product.

Does this make it more clear?

]]>Yes, again you are correct. I can’t remember why I had an implication arrow there but it’s fixed now.

]]>Yes, you are right. Thanks for pointing this out. After switching to a different LaTeX generator some formulas didn’t render correctly anymore. I hope I have fixed all of the places (in this page) where formulas were not rendered correctly anymore but if you seen any more then please let me know!

]]>You can use the same technique shown here to bind a VBO to a CUDA memory buffer, lock and process the memory buffer in CUDA then render the VBO in OpenGL as usual.

You mentioned “point data”. If this data represents a 3-dimensional mesh, then you will still need an index buffer to specify how the points can be connected to form triangles (or you can just render with GL_POINTS if you just want a point representation of your data).

]]>Sorry, the matrix representation of a complex number is not explained in this article. I will try to briefly explain it here.

We can represent a complex number as the matrix [math]\mathbf{C}[/math] which is the sum of two other matrices representing the real [math]\mathbf{R}[/math] and the imaginary [math]\mathbf{I}[/math] parts (note that bold, upper-case characters represent matrices):

[math]\mathbf{C}=\mathbf{R}+\mathbf{I}[/math]

Which can also be expressed in the more familiar form of the complex number:

[math]\mathbf{C}=a\mathbf{\hat{R}}+b\mathbf{\hat{I}}~~a,b\in\mathbb{R}[/math]

where [math]\mathbf{\hat{R}}{\equiv}1[/math] and [math]\mathbf{\hat{I}}{\equiv}i[/math].

The matrix equivalent of 1 is the 2 x 2 identity matrix:

[math]\mathbf{\hat{R}}=\begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix}[/math]

And as was mentioned in the section titled Powers of i the imaginary component [math]i[/math] can be treated as a 90° counter-clockwise rotation in the complex plane which can also be represented by a rotation matrix:

[math]\begin{array}{rcl}\mathbf{\hat{I}} & = & \begin{bmatrix}\cos{90^{\circ}} & -\sin{90^{\circ}} \\ \sin{90^{\circ}} & \cos{90^{\circ}}\end{bmatrix} \\ & = & \begin{bmatrix} 0 & -1 \\ 1 & 0\end{bmatrix}\end{array}[/math]

Now we can express the complex number in matrix form:

[math]\begin{array}{rcl}\mathbf{C} & = & a\mathbf{\hat{R}}+b\mathbf{\hat{I}} \\ & = & a\begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix}+b\begin{bmatrix} 0 & -1 \\ 1 & 0 \end{bmatrix} \\ & = & \begin{bmatrix} a & -b \\ b & a \end{bmatrix}\end{array}[/math]

So what you see in the section titled Rotors is the matrix form of a complex number and the [math]a[/math] and [math]b[/math] are the real and imaginary parts of a complex number and rotating a complex number (represented in matrix form) by the 2×2 counter-clockwise rotation matrix produces another complex number (represented in matrix form).

It is also interesting to note that if we express the equation [math]i^2=-1[/math] in matrix form we get:

[math]\begin{bmatrix} 0 & -1 \\ 1 & 0 \end{bmatrix}\begin{bmatrix} 0 & -1 \\ 1 & 0 \end{bmatrix} = -1\begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix}[/math]

which verifies that the square of the imaginary number is -1.

I hope this helps.

]]>Thanks for pointing this out. I have fixed the article now.

]]>In the example we are rotating the vector [math]\mathbf{p}=2\mathbf{i}[/math] 45° by the quaternion [math]q=[\cos\theta,\sin\theta\mathbf{k}][/math] but in order to perform this operation, we must express [math]\mathbf{p}[/math] as a **pure** quaternion in the form [math]p=[0,\mathbf{p}][/math]. (notice how vectors are expressed use bold-face characters and quaternions are expressed as normal (not bold) characters).

If the quaternion [math]q[/math] correctly rotated the vector [math]\mathbf{p}[/math] then the result should also be a **pure** quaternion (with no scalar part) and the magnitude of the **vector part** should be the same as the original vector (because a rotation should not scale the original vector) however this example shows that this is not the case.

The magnitude of the original vector is

[math]\begin{array}{rcl}|\mathbf{p}|&=&\sqrt{2^{2}}\\&=&2\end{array}[/math]

But the magnitude of the **vector part** of the resulting quaternion is:

[math]\begin{array}{rcl}|\mathbf{p}\prime|&=&\sqrt{\sqrt{2}^{2}+1^{2}}\\&=&\sqrt{2+1}\\&=&\sqrt{3}\end{array}[/math]

Which is not the same magnitude as the original vector.

If I wanted to compute the magnitude of the resulting **quaternion** then I would need to consider the quaternion’s scalar part according to the formula described in the section titled Quaternion Norm. But since I’m only interested in rotating a vector by a quaternion I only want to consider the result of the vector part (and thus discard the scalar part when I compute the magnitude of the resulting vector).

I hope this answers your question.

]]>The arcball camera is slightly more complicated and requires a few functions to define correctly so I’m wondering how I’m going to approach that one.

There is definitely an article about projection matrices planned but I probably won’t be able to get to it for another couple months…

]]>Thanks for pointing this out. It should actually be:

[math]q_1{\cdot}q_2[/math]

I recently switched LaTeX engines. The new one seems to be a bit more picky about separating parts of the equation for correct rendering.

]]>