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 Aug 26 '12 at 13:01
  • \$\begingroup\$ yes, but rot is a quaternion? \$\endgroup\$ – Will Aug 26 '12 at 13:03

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 Aug 26 '12 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\$ – Maik Semder Aug 26 '12 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 Aug 26 '12 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\$ – Maik Semder Aug 26 '12 at 13:57
  • \$\begingroup\$ Here is the code example for the transformation \$\endgroup\$ – Maik Semder Aug 26 '12 at 14:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.