Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

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

share|improve this question
    
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

2 Answers 2

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.

share|improve this answer
    
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
up vote 2 down vote accepted

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;
function rotateAroundWorldAxis(object, axis, radians) {
  rotWorldMatrix = new THREE.Matrix4();
  rotWorldMatrix.makeRotationAxis(axis.normalize(), radians);
  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.

share|improve this answer
    
"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

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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