To move a unit forward:

forward = Quaternion(0,0,0,1)
rotation.normalize() # ocassionally
pos += ((rotation * forward) * rotation.conjugated()).xyz().normalized() * speed

I think the trouble stemmed from how the Euclid math library was doing Quaternion*Vector3 multiplication, although I can't see it.

I have a vec3 position, a quaternion for rotation and a speed.

I compute the player position like this:

rot *= Quaternion().rotate_euler(0.,roll_speed,pitch_speed)
pos += rot.conjugated() * Vector3(0.,0.,-speed)

However, printing the pos to console, I can see that I only ever seem to travel on the x-axis.

When I draw the scene using the rot quaternion to rotate my camera, it shows a proper orientation.

What am I doing wrong?

Here's an example:

  • You start off with rotation being an identity quaternion: w=1,x=0,y=0,z=0

  • You move forward; the code correctly decrements the Z

  • You then pitch right over to face the other way; if you spin only 175deg it'll go in right direction; you have to spin past 180deg. It doesn't matter which direction you spin in, up or down, though

  • Your quaternion can then be something like: w=0.1,x=0.1,y=0,z=0

  • And moving forward, you actually move backward?!

(I am using the euclid Python module, but its the same as every other conjulate)

The code can be tried online at http://williame.github.com/ludum_dare_24_evolution/ The only key that adjusts the speed is W and S. The arrow keys only adjust the pitch/roll.

At first you can fly ok, but after a bit of weaving around you end up getting sucked towards one of the sides. The code is https://github.com/williame/ludum_dare_24_evolution/blob/cbacf61a7159d2c83a2187af5f2015b2dde28687/tiny1web.py#L102

  • 1
    \$\begingroup\$ What are you expecting. Multiplying two vectors is multiplying its components. So [6, 7, 8] * [0, 0, 1] = [0, 0, 8]. \$\endgroup\$
    – API-Beast
    Commented Aug 26, 2012 at 13:01
  • \$\begingroup\$ yes, but rot is a quaternion? \$\endgroup\$
    – Will
    Commented Aug 26, 2012 at 13:03

1 Answer 1


The rotation of the direction-vector using the quaternion is wrong, it must be:

    Pout = q * Pin * conj(q)

    Pin  -> input vector
    q    -> quaternion
    Pout -> rotated output vector

Details can be found here: Transformations using Quaternions

Code correction:

    pos += rot * Vector3(0.,0.,-speed) * rot.conjugated() 

Note: If the movement is still wrong, then roll_speed and pitch_speed are most likely absolute values, rather than the relative orientation change in this frame, then the first line would have to be:

    rot = Quaternion().rotate_euler(0.,roll_speed,pitch_speed)
  • \$\begingroup\$ I can quatvec3 but not vec3*quat - this is just how the libary is. So can you clarify if you mean (rv)*conj(r) or conj(r)*(r*v)? (roll/pitch/speeds are deltas for this 'tick') (I still have problems; it flies around a bit but after a while it stops flying, or starts moving when speed is 0. I begin to suspect problems with my rot not being normalised or something? \$\endgroup\$
    – Will
    Commented Aug 26, 2012 at 13:45
  • \$\begingroup\$ It is: (qv)*q' .. qv should return a quaternion, so the second operation should not be vec3*quat, but quat*quat \$\endgroup\$ Commented Aug 26, 2012 at 13:52
  • \$\begingroup\$ I tried also (q*Quat(0,0,0,-1)*conj(q)).xyz.normalized() * client.speed too. It all mostly works. And then, after quite a bit of flying around, you find yourself flying towards some side regardless of where you are pointing. \$\endgroup\$
    – Will
    Commented Aug 26, 2012 at 13:54
  • \$\begingroup\$ The formula in your last comment is simply wrong, you need the one from my post and in the link I gave you. \$\endgroup\$ Commented Aug 26, 2012 at 13:57
  • \$\begingroup\$ Here is the code example for the transformation \$\endgroup\$ Commented Aug 26, 2012 at 14:07

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .