Rotation Matrixes and quaternions

Started by
3 comments, last by Obs-D 10 months ago

Hello there,

I have this question because it happens than i can improve somewhat my game from the serverside if i get the answer to this.

  • Given than every one of the 4 corners of a square, are dots
  • Given than in the middle of the square there is another dot than works as the center of the relation between all the elements of the square.
  • Given a quaternion who simbolize the rotation of the object (dot) in the middle of the square.
  • Given than the rotation of the center dot provoke the equal rotation of all the rest of the square.
  • How can i get the new position of all the other dots which are not the center dot?

None

Advertisement
  • Subtract the position of the center of the square from each of the four corners.
  • Multiply each resulting vector by the desired rotation matrix. You could do quaternion-vector multiplication: q p q* (* is conjugate), but it's slower than building a 3x3 matrix from the quaternion and multiplying the matrix with each vector.
  • Add the position of the center of the square to the rotated vectors to get the rotated point positions.

To show why matrices are faster than quaternions:

// SSE optimized 4x3 matrix * vector4
	movss	4(%rdx), %xmm0
	pshufd	$0, %xmm0, %xmm0
	mulps	16(%rsi), %xmm0
	movss	(%rdx), %xmm1
	pshufd	$0, %xmm1, %xmm1
	mulps	(%rsi), %xmm1
	addps	%xmm0, %xmm1
	movss	8(%rdx), %xmm0
	pshufd	$0, %xmm0, %xmm0
	mulps	32(%rsi), %xmm0
	addps	%xmm1, %xmm0
	movaps	%xmm0, (%rdi)

Just 12 instructions. Meanwhile a scalar code (no SSE) matrix*vector is 27 instructions. On the other hand, scalar (no SSE) quaternion*vector is 88 instructions. This is with GCC 4.2.

There's no way an SSE-optimized quaternion could beat matrix*vector. Even if you use structure-of-arrays layout, it would be about 88 instructions to do 4 quaternion*vector, which is about 22 instructions per multiply throughput. So, best case SSE quaternion*vector would be almost twice as slow as SSE matrix*vector, and you would have to have the data in the right layout for it to be fast at all.

With AVX, the matrix*vector becomes just 9 instructions due to broadcast instructions, and quaternion is still only 11 instructions per multiply throughput if we use SoA layout.

IMO the only good use of quaternions is for storing and interpolating animation or for networking, where the size of the rotation representation is important and/or you need to slerp.

So you want to reconstruct a square in 3d-space given only its center-point and orientation-quaternion? You do need one more metric, that the (half)-length of its edges. If you have those 3 metrics, you can then reconstruct the square using the following method:

  1. Create one corner-point in local/object-space. Essentially, take Vector3(half-edge, half-edge, 0) to give you the upper-left corner. Make sure that which 2 coordinates you pick aligns with your coordinate-system.
  2. Transform this corner-point using the quaternion. This will rotate the point exactly how you describe.
  3. Add the center-point to that local rotated coordinate. You now have this points location in world-space

Repeat this step for the other points, which are permutations of the half-edge offset:

b) (half-edge, -half-edge, 0)
c) (-half-edge, half-edge, 0)
d) (-half-edge, -half-edge, 0)

And repeat steps 2-3 for each of them.

Let me know if I missed something in your question, or you got questions about my reply.

Will try what you guys has suggested here this weekend or next week and will let you know any question or so, thank you

None

This topic is closed to new replies.

Advertisement