I'm working on a game which involves walking your character on the surface of a sphere. Using the answer to Arbitrary Rotation about a Sphere, I've written my code as:

if (game.isKeyDown(37)) { // left
    this.quaternion.multiply(new THREE.Quaternion(0, Math.sin(-0.01), 0, Math.cos(-0.01)));

if (game.isKeyDown(39)) { // right
    this.quaternion.multiply(new THREE.Quaternion(0, Math.sin(0.01), 0, Math.cos(0.01)));

if (game.isKeyDown(38)) { // up
    this.quaternion.multiply(new THREE.Quaternion(Math.sin(-0.01), 0, 0, Math.cos(-0.01)));

if (game.isKeyDown(40)) { // down
    this.quaternion.multiply(new THREE.Quaternion(Math.sin(0.01), 0, 0, Math.cos(0.01)));

var qx = this.quaternion.x;
var qy = this.quaternion.y;
var qz = this.quaternion.z;
var qw = this.quaternion.w;
this.obj.position.x = 2 * (qy * qw + qz * qx) * radius;
this.obj.position.y = 2 * (qz * qy - qw * qx) * radius;
this.obj.position.z = ((qz * qz + qw * qw) - (qx * qx + qy * qy)) * radius;

Which works fine, however I would like to control the character in such a way that pressing up and down is equivelent to walking forwards and backwards (in the direction you are looking), whereas pressing left and right is the same as turning around on the spot.

I understand that I will have to store a forward vector, but I'm not clear on how that relates to the quaternion which allows the character to walk on the surface of the sphere.

Another problem I've got to overcome is making sure the character on the surface of the sphere is actually "looking" the way it is going, at the moment I'm modelling the player as another sphere, but in the futuer it will be a proper model which will need to orientate itself.


Store a direction vector as a tangent to the sphere. When you move, you can take this tangent, the normal vector (normalized position on the sphere) and cross them to get a general axis to rotate around. If you're limiting all movement to a single 2D plane (you're just using a single angle), for direction all you need is a sign (+1 or -1) to multiply your movement angle by. You can also use the sign to calculate a facing rotation about the sphere normal vector (or to just flip the character about its local Y axis) to orient your character properly.

  • \$\begingroup\$ Thanks, this helped a lot. Incase other people arrive at this question, I also found gamedev.net/topic/… which has some nice pointers. \$\endgroup\$
    – Tom Leese
    Jul 17 '13 at 18:28

The following code solves one of the OP's problem. That of the player turning around himself on a sphere, when pressing left and right (or d and a) buttons

                case 68: //D
                    this.quaternion.multiply(new THREE.Quaternion(0, 0, Math.sin(-0.01), Math.cos(-0.01)));
                case 65: //A
                    this.quaternion.multiply(new THREE.Quaternion(0, 0, Math.sin(0.01), Math.cos(0.01)));
  • 1
    \$\begingroup\$ It's not quite clear what you want to say about this code you've included. Can you please edit your answer to include some description about why you've chosen this specific code? \$\endgroup\$
    – DMGregory
    Jan 20 '19 at 16:14
  • \$\begingroup\$ Alright, I did just that. \$\endgroup\$ Jan 21 '19 at 21:00
  • \$\begingroup\$ Some insight about how or why this works would be nice. Assume that your reader finds quaternions mysterious, and wants to know not just what numbers to use, but why those numbers work, or how they can figure out that those numbers are right. Successfully demystifying the choices you've made here will make them want to give you upvotes. :) \$\endgroup\$
    – DMGregory
    Jan 21 '19 at 21:28
  • \$\begingroup\$ @DMGregory Honestly I have no idea because I'm not good with quaternions. I was looking for the same exact thing as the OP and came across this thread. It was just a random thought: what If I change it in order to be appled to the z parameter of the quaternion? Voila it worked. \$\endgroup\$ Jan 21 '19 at 21:55

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.