2
\$\begingroup\$

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

\$\endgroup\$
2
  • \$\begingroup\$ What is sphere.rotation.X? What does X signifies here? Does it mean rotation around x axis? \$\endgroup\$
    – Shashwat
    Sep 19 '12 at 8:59
  • \$\begingroup\$ 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 \$\endgroup\$
    – kaipr
    Sep 19 '12 at 13:46
2
\$\begingroup\$

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: https://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.

\$\endgroup\$
1
  • \$\begingroup\$ "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. \$\endgroup\$
    – Shashwat
    Sep 21 '12 at 6:32
0
\$\begingroup\$

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.

\$\endgroup\$
4
  • \$\begingroup\$ 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. \$\endgroup\$
    – kaipr
    Sep 19 '12 at 12:02
  • \$\begingroup\$ What is sphere.rotation.x?? How are you drawing the sphere? \$\endgroup\$
    – Shashwat
    Sep 19 '12 at 12:06
  • \$\begingroup\$ 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. \$\endgroup\$
    – Shashwat
    Sep 19 '12 at 15:38
  • \$\begingroup\$ 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. \$\endgroup\$
    – kaipr
    Sep 20 '12 at 19:56

You must log in to answer this question.

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