My question is an extension of this question: How to find rotation matrix between two vectors in THREE.js
If I had a Vector3, and a Vector3 normal to it describing the orientation of a 3D object, how would I go about finding the rotation matrix between this vector group and a transformation of this vector group available to me as already translated group of vectors?
Here's a visual to make it clearer :
I want to use proper THREE.js utilities find the quaternion which rotates the rotation of a group described by v1 and v1n to the rotation of the same group described by v1' and v1n'. The rotation pivots of these states are described by the points p1 and p1'.
From the above answer I know how to get the rotation from one Vector3 to another, but if I were to use that method for my use case, I would not be handling the 3rd degree of freedom of the rotation (assuming yaw, pitch, roll is used to describe the rotation).
My answer #2: Not relying on the orientation of the 2 groups.
Let's again say we want to rotate v1 and v1n to v2 and v2n. We can use .setFromUnitVectors(v1, v2) to get quaternion Q1 rotating v1 to v2. v1n will rotate into v1nrot1, which is normal to v2, but is not v2n. We can use .setFromUnitVectors(v1nrot1, v2n) again to get quaternion Q2 rotating v1nrot1 to v2n. This 2nd rotation will not affect v1rot (=v2) because v1rot is normal to v1nrot1 and v2n. If these were not normal, there would be an extra step to get normals. Finally, v1rot dot v2 = 1 and v1nrot2 dot v2n = 1 showing the Q2Q1 rotation worked. The code is commented.
<!doctype html>
<html><!-- https://stackoverflow.com/questions/61619752/ -->
<head>
<title> SO.html </title>
<style type="text/css">
* { font-family:monospace; font-size:16px; }
</style>
<script src="http://threejs.org/build/three.js"></script>
<script type="text/javascript">
"use strict";
const k57=180/Math.PI;
var div1elt;
window.onload = function() {
div1elt = document.getElementById("div1");
// get v1 and v1n
print(" -- v1 and v1n");
var v1 = new THREE.Vector3(1,2,3).normalize();
var vtmp = new THREE.Quaternion(1,0,0).normalize();
var v1n = v1.clone().cross(vtmp).normalize();
printv("v1", v1);
printv("v1n", v1n);
print("v1 dot v1n", v1.dot(v1n));
// get v2 and v2n
print(" -- v2 and v2n");
var v2 = new THREE.Vector3(4,3,2).normalize();
var vtmp = new THREE.Quaternion(0,0,1).normalize();
var v2n = v2.clone().cross(vtmp).normalize();
printv("v2", v2);
printv("v2n", v2n);
print("v2 dot v2n", v2.dot(v2n));
// get Q1 that rotates v1 to v1rot (and v1n to v1nrot1)
var Q1 = new THREE.Quaternion().setFromUnitVectors(v1, v2);
// get Q2 that rotates v1nrot1 to v1nrot2
// Q2 will not rotate v1rot because v1nrot1 and v2n are normal to v1rot
var v1nrot1 = v1n.clone().applyQuaternion(Q1); //
var Q2 = new THREE.Quaternion().setFromUnitVectors(v1nrot1, v2n);
var Q12 = new THREE.Quaternion().multiplyQuaternions(Q2,Q1);
// print Q12
printq(" -- Q12 --",Q12);
// now see if Q12 works
print(" -- check results");
var v1rot = v1.clone().applyQuaternion(Q12);
print("v1rot dot v2", v1rot.dot(v2).dd(1,5));
var v1nrot2 = v1n.clone().applyQuaternion(Q12);
print("v1nrot2 dot v2n", v1nrot2.dot(v2n).dd(1,5));
};
Number.prototype.dd = function(b4, af) { // formats nn.nnn
// usage: string = n.dd(2,3) or (2).dd(2,3)
if (isNaN(parseFloat(this)) || !isFinite(this)) return this;
var pfx = "", pos, b4s, b4v, afs, afv;
var s = String(this+.5*Math.pow(10,-af));
if (s.substring(0,1) == "-") { pfx = "-"; s = s.substring(1); b4-=1; }
if (s.substring(0,1) == "0") s = s.substring(1);
if ((pos = s.indexOf("."))==-1) s+=".";
b4s = s.substring(0,pos); b4v = b4s.length;
afs = s.substring(pos+1); afv = afs.length;
if (b4>b4v) pfx+= "0".repeat(b4-b4v);
if (af>afv) afs +="0".repeat(af-afv);
if (af<afv) afs = afs.substring(0,af);
return pfx+b4s+((af!=0)?".":"")+afs;
};
function printq(txt, q) { // print q
var ang = Math.atan2(Math.sqrt(q.x*q.x+q.y*q.y+q.z*q.z), q.w);
var len = Math.sqrt(q.w*q.w+q.x*q.x+q.y*q.y+q.z*q.z);
print(txt, q.w.dd(2,5),q.x.dd(2,5),q.y.dd(2,5),q.z.dd(2,5),
"[len="+len.dd(2,5)+", ang="+(ang*k57).dd(4,1)+"]");
}
function printv(txt, v) { // print v
var len = Math.sqrt(v.x*v.x+v.y*v.y+v.z*v.z);
print(txt, v.x.dd(2,5),v.y.dd(2,5),v.z.dd(2,5),
"[len="+len.dd(2,5)+"]");
}
function print(what) { // print
var s="";
for (var i1=0; i1<arguments.length; i1+=1) {
if (s != "") s += ", ";
s+= arguments[i1];
}
div1elt.innerHTML += s + "<br />";
}
</script>
</head>
<body>
<div id="div1"></div>
</body>
</html>