As in the picture, within the parent plane there are 3 points, red, green and blue. The purple and gold represents two objects between these 3 points. Assume I’ve observed the world positions of the 3 points before and after the rotation of the plane. How can I calculate the quaternion/euler angles based on the positions of the 3 points for the plane? Further more, assume there are only the purple and gold objects and the 3 points. How to calculate the translation and quaternions for the two objects based on the positions of the 3 points?
⌈ red xi green xi blue xi 0 ⌉
red yi green yi blue yi 0
red zi green zi blue zi 0
⌊ 0 0 0 1 ⌋
Now you want matrix B that maps from 1st set of coords to 2nd set:
A2 = B * A1
This is now a very complex math problem that requires advanced skills to arrive at the solution:
B = A2 * inverse of A1
Once you have B, you can invoke 3js built-in magic to retrieve the quaternion, translation and scale.
Forgive me if I miss understood, what exactly do you mean by “advanced skills”. Based on your reply, looks like I only need to calculate the inverse of A1. And after I’ve got B, I can transfer the matrix to quaternions/euler, translation.
Yes. Unfortunately the explanation is too long to write down here, but the most of it boils down to Quaternion’s setFromRotationMatrix method taking Matrix4 as an argument, which means you have to take your actual 3x3 matrices and pad them with random 0s and 1s to make it work.
It doesn’t work. I don’t know where I did wrong. I build A1 and A2 by .makeBasis(v1, v2, v3). v1, v2, v3 are the coordinates of the 3 points before and after the rotation. And calculated A1.invert(), and B = A2.multiply(A1.invert()). Finally quaternion Q.setFromRotationMatrix(B). It gives me a rotation that isn’t the same as the target.
@hofk Thanks for the info, if I understand it correctly, I still need to transfer the original Quaternion to Matrix in order to find the invert of it, even though I can get the original Quaternion by setFromBasis. Is that correct?
My goal was just to eliminate the many operations with matrices and to limit myself to the quaternion for the orientation in space and to .position.set( ) for the position.
THREE.Quaternion.prototype.setFromBasis = function( e1, e2, e3 ) { ...
------
// points and corresponding basis in arrrays
const points = curve.getPoints( ls );
...
// bases in arrays, not in a matrix
t = .. ; // tangents array
n = .. ; // normals array
b = .. ; // binormals array
----------
// set orientation and position in each case
shuttle.quaternion.setFromBasis( t[ iShuttle ], b[ iShuttle ], n[ iShuttle ] ); //orientation in space
shuttle.position.set( points[ iShuttle ].x , points[ iShuttle ].y, points[ iShuttle ].z ); // position
iShuttle ++; // next point
But maybe I’m missing a different requirement in your problem?
Try to see if you can get further with the shuttle approach.
Welp, this is basically a matrix without creating Matrix4 instance. But yes, with your approach OP could probably do 2 quaternions and then calculate the rotation between them with .conjugate() + .multiply()
Of course, extracting the components of the basis vectors into constant values is equivalent to a matrix. But this also within the function. One saves the creation of the matrix in the application code. With the quaternion it seems clearer to myself.