DTids
DTids

Reputation: 110

Three.js camera.rotation.y to 360 degrees conversion

I'm trying to rotate a 2D object (in a GTA style minimap overlay) relevant to the Three.js camera rotation.y value in my 3D scene.

The problem is the radians returned from camera.rotation.y value are a bit strange, going from 0 > -1.4 radians through the first 45 degrees, back from -1.4 > 0 radians through to 90 degrees, 0 > 1.4 radians through to 270 degrees, and 1.4 > 0 radians to 360 degrees.

Does anyone know a way to convert or translate these values into 360 coords?

I'm using PerspectiveCamera and OrbitControls.

Thanks in advance!

Upvotes: 2

Views: 7597

Answers (3)

Wilt
Wilt

Reputation: 44393

camera.rotation is a so called Euler angle as you can also read here in the three.js docs for THREE.Object3D (which is the base class for the THREE.Camera class). You cannot simply get an angle to a certain axis directly from the euler angle, since the angle you get depends on the order of the euler.

Upvotes: 1

Kevan Stannard
Kevan Stannard

Reputation: 1067

I think this might be related to converting from quaternion rotations. Not sure if the following example is correct but it might help in you finding the solution.

const euler = new THREE.Euler();
const rotation = euler.setFromQuaternion(camera.quaternion);
const radians = rotation.z > 0
    ? rotation.z
    : (2 * Math.PI) + rotation.z;
const degrees = THREE.Math.radToDeg(radians);

This results in degrees having a value from 0 to 360 but as the camera rotates the angle values seem to change at an inconsistent rate.

Here's a codepen that demonstrates this behaviour:

http://codepen.io/kevanstannard/pen/NdOvoO/

I used some details from the following question:

three.js perspectivecamera current angle in degrees

Edit #1

Based on the answer from @WestLangley my answer above is not correct, so just to document the improvement, here's some code based on West's solution:

// Set Y to be the heading of the camera
camera.rotation.order = 'YXZ';

And then

const heading = camera.rotation.y;
const radians = heading > 0 ? heading : (2 * Math.PI) + heading;
const degrees = THREE.Math.radToDeg(radians);

And a better codepen

http://codepen.io/kevanstannard/pen/YNJgXd

Upvotes: 5

WestLangley
WestLangley

Reputation: 104833

If you set

camera.rotation.order = "YXZ"

( the default is "XYZ" ) the Euler angles will make a lot more sense to you:

rotation.y will be the camera heading in radians

rotation.x will be the camera pitch in radians

rotation.z will be the camera roll in radians

The rotations will be applied in that order.

For more information, see this stackoverflow answer.

three.js r.84

Upvotes: 3

Related Questions