How to rotateOnAxis to specified angle?

Hi all,

cube.rotateOnAxis(xAxis, angle);
Gives me the correct rotation, but how can I let it rotate to a certain angle/radian instead of rotating the amount of angle given?

I use this rotation instead of a normal cube.rotation.x so that when my object rotates the rotation is still relative to the object instead of the scene.

Perhaps try setRotationFromAxisAngle?

1 Like

I don’t know exactly what you want to achieve. :slightly_smiling_face:

I’m just about to place mirrors in a room and turn them correctly. It works like this:

reflector.rotateY( twist );
reflector.rotateOnAxis ( new THREE.Vector3( 1,0,0), tilt );
reflector.position.set( x, y, z );

*2020-04-15 10.19.28 *

A live example would be helpful.

1 Like

You can achieve a similar effect with quaternions. You have to define a quaternion that represents your target rotation. Then use Quaternion.rotateTowards() per simulation step that will rotate your object by a given angular step towards the target. The following example demonstrates this approach:

https://threejs.org/examples/webgl_math_orientation_transform

We actually adapted this approach from Unity where it’s a popular method of the quaternion class:

2 Likes

This seems to only work on one axis at a time, overwriting the previous rotations on different axis?

My example would look like yours so the tilting is indeed correct but the “tilt” value has to be the endpoint for me instead of giving the amount of tilting.

This because I am updating the “tilt” to go the a certain degree/radian when updating.

So or I need another rotation method or I need a function that calculates how big the “tilt” value needs to be at that moment with the degrees given.

I need it to be instant on update instead of giving the speed at which it has to move, but I am trying it out at the moment to see if that is an option.

That’s right, Object3D.setRotationFromAxisAngle overwrites whatever other rotations you have on that object. Do I have it right that you want to rotate to a specific angle derived from multiple rotations, but you don’t want to rotate by an initial angle? If so, you could always just reset the object’s rotation and then apply as many axis angles as you want, eg:

var EMPTY_QUAT = new THREE.Quaternion();

cube.setRotationFromQuaternion(EMPTY_QUAT);
cube.rotateOnAxis(axis1, angle1);
cube.rotateOnAxis(axis2, angle2);
...

Of course if these axes are actually the X axis, Y axis, and Z axis of the object’s local coordinate system, you can make your life even easier by just using an Euler.

1 Like

lookAt() would be instant.

1 Like

As the answers show, there are many possibilities. Maybe this variant based on my example?

 // start
let previousTilt = 0;

//   ... in a loop ...

newTilt  = // (what you want, as a target value )

tiltChangeValue = newTilt - previousTilt

reflector.rotateOnAxis ( new THREE.Vector3( 1,0,0), tiltChangeValue );

// ... ...

UPDATE:

With a loop:
better define vectorX = new THREE.Vector3( 1,0,0 ) before and use it

1 Like

Resetting the rotation before rotateOnAxis, really smart and easy!
Marking this as solution because it does do what my main question was.

It unfortunately does not fix my issue that I wanted to solve as shown below because I might need a different rotation approach.

As you can see the rotation axis does not rotate with the object so my alpha (xAxis) movement is wrong after rotating my object 90 degrees on the zAxis.

That was also something that I tried in the beginning but giving it plus and minus values did not work as intended and after trying to counteract that I was looking for a different less complicated way.

Unfortunately not giving the result I hoped for, but I guess its not the right fit for this but rather for looking at other objects. Still nice to know about.

Thanks all for your replies! The solution on the question was found but unfortunately it did not fix my rotation issue I have.

Guess it is back to the drawingboard and see how I can rephrase my question and hope to find a solution.

By the way, apologies if you’ve tried this already, but have you experimented with a Euler? something like:

var euler = new THREE.Euler(0, 0, 0, 'XYZ');
...
euler.set(alpha, beta, gamma);
cube.setRotationFromEuler(euler);

You can experiment with changing that 'XYZ' to 'YXZ', 'ZYX', etc until it’s behaving the way you intend. (I often find it hard to keep a series of axis-rotations clear in my head so I often just trial-and-error till I get what I need.)

If you get a decent answer here it would be great if you also answer https://stackoverflow.com/questions/57311356/rotating-an-object-properly-around-a-pivot-point-given-axis-and-angle

Rotation one of the unsolved problems of our time see https://discourse.threejs.org/t/re-rotation-problems/9312