Gimbal lock at y axis 90 degrees - three.js

I found a problem with rotations.
Using the transform controls helper, if I rotate a mesh on the Y axis, when I reach 90 degrees everything is flipped by -180 degrees.
I think this is due to the software avoiding gimbal lock, how to avoid it?
That is, I would like the x- and z-angles to remain 0 degrees in the display.
I tried even on the threejs editor (https://threejs.org/editor/) and it occurs even there.
Please help me :)!

What you are describing is has nothing to do with Gimbal lock.
three.js is quaternion-based. An equivalent Euler angle representation is provided for convenience.
Euler angles are not unique; there are many Euler angles that represent the same orientation. See this answer for info on how Euler angles work in three.js.
If you want to rotate an object on the y-axis only, and have object.rotation.y be continuous, you can do so by changing the rotation order like so:
object.rotation.order = 'YXZ';
three.js r.87

Related

threejs: How to perform rotation of object around it's local axes?

I am trying to rotate object on it's local axis using absolute rotation values. I am facing two issues
1. It looks like my object is rotating around world axes. For example set X, Y and Z to 45 degrees and try changing X.
2. If Y is set to 90 degrees, I get into gimbal lock issue.
I am using quaternion by setting rotation as follow
cube.quaternion.setFromEuler(new THREE.Euler(x, y , z));
A demo snippet is JSFiddle
I came across this article ThreeJS - rotation around object's own axis, but that didn't helped me.
I have been trying different solution using Euler and Matrix but still not able to make it work.
Looking for help to figure out the solution to this problem.

Unity Rotation & Quaternions

I'm learning Unity and I have a question.
I dont understand why this line resets the rotation to 0,0,0. All I'm doing is re-assigning its euler values?
transform.rotation =
Quaternion.Euler(transform.rotation.x,
transform.rotation.y,
transform.rotation.z);
The reason I'm doing this is because I need to lock one axis and keep the others changing. So I thought I could do it like this after the changes in x and z axes occur:
transform.rotation = Quaternion.Euler(transform.rotation.x,
LOCKED ROTATION VALUE,
transform.rotation.z);
I'm sure its simple but I cant find out whats wrong.
Thanks in advance.
Here is some documentation with transform.Rotate(). I'd use this one for rotating.
// Here is an example if you want to just rotate the Z axis.
transform.Rotate(new Vector3(0, 0, 10f) * Time.deltaTime);
Also, here is some other documentation on Quaternion. You could use functions like RotateTowards.
If your game object has a rigidbody on it then you can lock the rotation of it in Unity. Click on the game object and under the Rigidbody component click Constraints and then click the axis under Freeze Rotation.
You are using transform.rotation as if it is exposing Euler angles (which it is not). If you want the Euler angles from your rotation, you have to do this:
transform.rotation =
Quaternion.Euler(transform.rotation.eulerAngles.x,
transform.rotation.eulerAngles.y,
transform.rotation.eulerAngles.z);

Turn off clipping in a d3 projection

I have a projection that does not need clipping. Neither anti-meridian or small circle clipping is there a way to not use either
Turns out there is this solution. Set the clip angle to 181 degrees.
projection(globeProjection.clipAngle(181))
Don't know if this is doing a bunch of calculation and if it is possible to do better

How to copy the rotation value of a sprite to a plane?

I was wondering if there is a way to copy the rotational information of a sprite into a plane. It seems that for the sprite the rotation is set within the material and it is just one value. I tried copying the matrix of the sprite into that of the plane but had no luck.
Sprite rotation is defined in WebGL as you can read in SpritePlugin.js. Thus, if you wish to copy the rotation of an existing sprite in your scene, the easiest way may be to use quaternion. They allow better defining than x/y/z-angle defined ones (Euler rotations) as they ask for the rotation axis and the angle value. In your context, at each camera movement you modify a quaternion. You set it with quaternion.setFromAxisAngle(axis,angle). Then apply it to the plane with plane.setRotationFromQuaternion(quaternion).
Math side :
The axis would be the cross product between the vectors lastCameraPosition-sprite.position and actualCameraPosition-sprite.position,
the angle, the one between those vectors, got with the acos of their dot product divided by the product of their lengths.
For more about those maths, functions getMouseProjectionOnBall and rotateCamera in TrackBallControls are of great interest.
Hope it helped !

Rotation, using Quaternions

I have the problem of rotating my object correctly. What I need is to create a line ( along x-axis) grabbed to the point so that when you move it, horizontally, vertically or a combination of those two movements, the end of the line circles part of the sphere plane and the beginning of the line stays at rest.
I am using the bullet physics engine, which provide objects like quaternions and functions to set their values e.g. using Euler angles or just creating 3 quaternions, filling their fields (W,X,Y,Z) and finally multiplying them, getting the final quaternion.
I've tried to use Euler angles and when I used EulerYXZ setting (only Yaw and Roll) it works well. But when I add pitch (which should be rolling in the direction of the line's axis) object's do rotate, but it doesn't circle the sphere any more. Probably my additional rotation incorporated some dislocation and I don't know how to figure it out.
Firstly, I created Quaternions which represent yaw and roll like this :
btQuaternion qx,qy,qz,
qx.setW(1);
qx.setX(0);
qx.setY(0);
qx.setZ(0);
qy.setW( btCos( -x*DEGREE/2.0f )); //x is the example angle value, * DEGREE provides radians
qy.setX(0);
qy.setY(btSin( -x*DEGREE/2.0f ));
qy.setZ(0);
qz.setW(btCos(( y+inclined )*DEGREE/2.0f ));
qz.setX(0);
qz.setY(0);
qz.setZ( btSin( (y+inclined)*DEGREE/2.0f ));
Now I can get final quaternion by multiplying them:
TransformStick.setRotation(qx*qy*qz);
How should I add rolling along the line's axis in order not to change the line's end position ?

Resources