Find relative position of axes of cube after rotation - rotation

I am rotating a cube through a series of 90 degree rotations using quaternions and I want to be able to get relative positions of the quaternions after a rotation compared with its original position that I have stored.
IE I'd like to know which axis is now equivalent to the original x axis (and if it is inverted), and so on...
I'm using threejs, but I'm sure that's not necessary for answering.

Use this pattern to determine the direction the x-axis is pointing after applying a series of rotations.
var dir = new THREE.Vector3( 1, 0, 0 );
dir.applyQuaternion( q1 );
dir.applyQuaternion( q2 ); // etc...
To see it visually, you can add axes as a child of your cube mesh. The axes will be rotated automatically.
var axes = new THREE.AxisHelper( 100 );
mesh.add( axes );
three.js r.71

Related

Is it possible to rotate a cube environment map 180 degrees around Y axis?

I'd like to rotate a cube map about Y axis by 180 degrees.
scene = new THREE.Scene();
scene.background = new THREE.CubeTextureLoader()
.setPath( '/path/to/my/docs/' )
.load( [ 'posX.jpg', 'negX.jpg',
'posY.jpg', 'negY.jpg',
'posZ.jpg', 'negZ.jpg' ] );
// this doesn't work
scene.background.rotation.y = Math.PI;
How can I do that?
Pity but in Three.js I have no possibility to rotate my cube map using rotation parameter:
scene.background.rotation.y = Math.PI;
Solution
The simplest solution in my case (I want to rotate it around Y axis) is to rename 4 images that form the sides of the cube map to reorient that cube (skybox) 180 degrees.
We must remember that by default Three.js Camera looks towards -Z direction.
Look at these pictures. Left image depicts a default 6-image-placement to form a cube map. Right image represents 180-degrees-about-Y-axis reoriented cube.
Renaming process
So, for reorientation you just need to rename 4 source files. Here's a table showing you how to:
Default name
Renamed
posX.jpg
negX.jpg
negX.jpg
posX.jpg
posZ.jpg
negZ.jpg
negZ.jpg
posZ.jpg
And after renaming process, rotate posY.jpg and negY.jpg images by 180 degrees.

Rotate around World Axis

I tried to rotate an object arount the Worlds-Y-Axis, with
myObject.rotateOnWorldAxis(new THREE.Vector3(0,1,0),THREE.Math.degToRad(1));
but the result was, that the object is only rotated in object space.
To be sure that I used the correct method I looked into the documentation and found that there are three methods to rotate an object:
.RotateY(rad) // rotate in Local Space
.rotateOnAxis(axis,rad) // rotation in Object Space
.rotateOnWorldAxis(axis,rad) // rotation in World Space
It seems that I used the correct method.
Is this a bug or an understanding problem on my side?
Here is a JSFiddle which illustrates my problem (the blue cube should rotate around the world axis).
Here is a second Fiddle where thy cyan cube is a child of another object.
It looks to me like your real question isn't regarding world space or object space rotations, cause those are working as expected in your examples.
You probably meant, how to change the point of rotation of an object. If that is the case, you have two options, you can either translate all your geometry vertices in respect to a pivot point of rotation. That way, your pivot will be centered at (0,0,0) and your vertices will rotate in respect to that.
mesh.geometry.translate( x, y, z );
Or you can make your object a child of a different Object3D (pivot), position your original mesh similarly to what was described above and rotate your pivot mesh.
var cube = new THREE.Mesh( geometry, material );
var pivot = new THREE.Object3D();
cube.position.set( 0, 12, 30 ); // offset from center
pivot.add( cube );
scene.add( pivot );
//...
pivot.rotation.y += Math.PI/2;
JSFiddle

Generate shape in three.js from multiple elements

Is there a way in three.js to create a poly from multiple individual elements, rectangle for example.
I have attached an example.
I am using:
for(i = 0; i<5; i++){
var rand = Math.floor(Math.random() * 50)+1000;
var material = new THREE.MeshBasicMaterial({
color : "#ff"+i+ rand,
side : THREE.DoubleSide,
transparent : true,
opacity : 1
});
var mesh = new THREE.Mesh( geometry, material );
if(angle) mesh.rotation.y = angle;
mesh.position.set( loop+1, 4,4);
scene.add( mesh );
}
When I apply roatation mesh.rotation.y = angle; it doesn't come up with my below design, I rather get a cross + because the panel rotates on it's y from center, not from corner...
Thank you
The
There are 3 ways to achieve what you're trying to do. The problem you are facing stems from transform origin, as you noted, origin defaults to position [0,0,0]. So, your options are:
build a transform matrix using a different transform offset for rotation, this is probably an overkill for simple use-cases.
translate geometry to not be centered on [0,0,0], for example you can move the whole quad (your geometry) right so that the left edge of the quad aligns with [0,0,0], then, when you rotate, left edge will stay put.
embed Mesh inside a Group, rotate the Mesh and translate (position.set(....)) the Group.
no matter which route you take - you will still have to deal with the some trigonometry as you will need to compute the position for the next segment to align with the edge of the previous one.
One more way around that is to build the following type of structure
Group[
Mesh 1,
Mesh 2,
Mesh 3,
Group [
Mesh 4,
Mesh 5,
Mesh 6,
Group [
Mesh 7
]
]
]
Last group is unnecessary, it's there purely for consistency.
As far as the trigonometry that I mentioned - it's simple Sin and Cos stuff, so it should be quite simple. Here is some pseudo-code that you'll need:
prevPosition, prevAngle //position and angle of previous segment
// Compute next segment transform
nextPosition.x = Math.cos(prevAngle)*segmentSize + prevPosition.x;
nextPosition.z = Math.sin(prevAngle)*segmentSize + prevPosition.z;

THREE.js Update rotation property of object after rotateOnWorldAxis

I am trying to use rotateOnWorldAxis to rotate my mesh object. Before I apply the rotations, the mesh has its rotation data as Euler object with rotation value for each axis.
in mesh.rotation:
// Euler (_x: 1.5707963267948961 _y: 1.3439035240356314 _z: 3.141592653589793)
I have some angles that I would like my mesh to rotate on each axis, so I am doing the following:
// define axis vectors and angles
const xAngle = some angle in Radians
const xAxis = new THREE.Vector3(1, 0, 0);
...same for Y and Z axis
// apply rotateOnWorldAxis
mesh.rotateOnWorldAxis(xAxis, xAngle);
...same for Y and Z axis
After using rotateOnWorldAxis method on my mesh object, I can visually see that my mesh has rotated correctly. However, when I inspect the object after applying the rotations, the mesh.rotation property does not change and still contains values from before the rotations.
In fact, all of its properties regarding transformation (e.g., matrix, matrixWorld, position, quaternion) remain unchanged, while the rendered mesh does rotate visually.
How do I trigger my mesh object to update all of its transformation data after applying rotateOnWorldAxis?

Rotate camera based on angle

I would like to rotate an object on a certain angle along Y axis.
Based on this answer How to rotate a Three.js Vector3 around an axis? I suppose to get an updated vector.
My code is :
var vec = new THREE.Vector3( 0,0,0 );
var axis = new THREE.Vector3( 0,1,0 );
var angle = Math.PI / 2;
vec.applyAxisAngle( axis, angle );
I'm using r67 and it returns me 0,0,0. I've tried r69 as well and it is returns me the same. I'm not quiet ready to move to r69. Could you guys tell me please how to do the same thing but using r67. Thanks.
Your are rotating vector (0, 0, 0) which is center and whatever angle you use to rotate center around any axis you will always get (0, 0, 0). Just imagine you are doing simple 2d rotation. After all, rotation around Y axis can be viewed as 2d rotation in X-Z plane.
Try with some other values for vec variable, for example (1, 0, 0) or (0, 0, 1) and you will see results

Resources