Rotate sphere in Javascript / three.js while moving along x/z plane

I have a sphere/ball in three.js which I want to "roll" around on the x/z plane. For the z axis I could simply do this no matter what the current x and y rotation is:

``````sphere.roll_z = function(distance) {
sphere.position.z += distance;
sphere.rotation.x += distance > 0 ? 0.05 : -0.05;
}
``````

But how can I roll it along the x axis? And how could I properly do the roll_z? I've found a lot about quaternion and matrices, but I can't figure out how to use them properly to achieve my (rather simple) goal.

I'm aware that I have to update multiple rotations and that I have to calculate how far to rotate the sphere to match the distance, but the "how" is the question. It's probably just lack of mathematical skills which I should train, but a working example/short explanation would help a lot to start with.

Here is an example of how the rotation goes wrong (WASD movement): http://js.blockheaven.net/simple.html

-
What is sphere.rotation.X? What does X signifies here? Does it mean rotation around x axis? –  Shashwat Sep 19 '12 at 8:59
Yes, and while the x axe remains the same and always follows the "world" z axe, z and y rotation axes get altered. This is an example of how it goes wrong (WASD movement): js.blockheaven.net/simple.html –  kaipr Sep 19 '12 at 13:46

Lets say `d` vector contains the distance you want to roll on `x` and `z` axis as `d.x` and `d.y` respectively.

Let `R` be the radius of the sphere (which you haven't mentioned).

Now for a distance of `2*pi*R`, your sphere makes a full rotation of `2*pi` radians (360 degrees)

So for a distance of `d`, it will rotate `d/R` radians.

Rotation for x and z axis will happen in exactly the same way.

``````sphere.roll_x = function(distance) {
sphere.rotation.z += distance.x / R;   //Rotation around z axis
sphere.position.x += distance.x;
}

sphere.roll_z = function(distance) {
sphere.rotation.x += distance.z / R;   //Rotation around x axis
sphere.position.z += distance.z;
}
``````

First do rotation, then translate it.

-
While this might help to find out how far to rotate it (couldn't test yet), the main question is how to rotate it along the "main" x axis. I can't just add something to x because the x rotation axis of the sphere gets altered by altering it's z axe. –  kaipr Sep 19 '12 at 12:02
What is sphere.rotation.x?? How are you drawing the sphere? –  Shashwat Sep 19 '12 at 12:06
I think your sphere is revolving around x-axis rather than rotating on its own axis. First do the rotation and then translate it. I've edited my answer. You can check if it is satisfactory. –  Shashwat Sep 19 '12 at 15:38
I've found the solution by myself now and posted it as answer. There doesn't seem to be a simple solution just because of how 3D rotations work (objects just need their own axes). Maybe I wasn't clear enough of what I wanted, still thank you for the tips and effort. –  kaipr Sep 20 '12 at 19:56

After searching arround for hours, digging through three.js code and commits I found out which code snippets do what I was intending to do and how to make them run with the current three.js version (documentation and all stackexchange answers are outdated).

``````// Rotate an object around an arbitrary axis in world space
var rotWorldMatrix;
rotWorldMatrix = new THREE.Matrix4();
rotWorldMatrix.multiplySelf(object.matrix);
object.matrix = rotWorldMatrix;
object.rotation.setEulerFromRotationMatrix(object.matrix);
}
``````

Original by Cory Gross found at: http://stackoverflow.com/questions/11060734/how-to-rotate-a-3d-object-on-axis-three-js?rq=1 (but getRotationFromMatrix is outdated).

This method rotates the object based on world axes aka rolling a ball on the floor while the camera is fixed. To use this, it needs to know which axe (x, y, z) of the object it should rotate:

``````var xAxis = new THREE.Vector3(1, 0, 0);
var yAxis = new THREE.Vector3(0, 1, 0);
var zAxis = new THREE.Vector3(0, 0, 1);
``````

Now, because I want to move it by a certain distance of pixels, to calculate the angle to rotate it:

``````var angle = distance / (2 * Math.PI * object.boundRadius) * Math.PI;
``````

And there is my roll_z function:

``````sphere.roll_z = function(distance) {
this.position.z += distance;

var xAxis = new THREE.Vector3(1, 0, 0);
var angle = distance / (2 * Math.PI * this.boundRadius) * Math.PI;
rotateAroundWorldAxis(this, xAxis, angle);
}
``````

Hope this might help others trying to achieve the same thing from going crazy like I was.

-
"var angle = distance / (2 * Math.PI * this.boundRadius) * Math.PI;" I think I have also posted the same thing "sphere.rotation.x += distance.z / R;" Here sphere.rotation.x is the angle of rotation only. Also it should not be "distance.z / 2R" as you your expression calculates to. –  Shashwat Sep 21 '12 at 6:32