Last active
July 1, 2020 21:19
-
-
Save d3x0r/386f1320f0ee43a39a0983347362439e to your computer and use it in GitHub Desktop.
Twist JS Function combined
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// this = { x: xAngle, y:yAngle, z:zAngle, nL: |x|+|y|+|z|, nR:sqrt( xx+yy+zz ) } | |
// nR = normRectangular | |
// nL = normLinear | |
function twistQuaternion(theta) { | |
// function getBasis() { // computes xyz basis vectors (matrix) | |
// this is angle-angle-angle log-quaternion | |
const q = this; | |
if( !this.nL ) { // no rotation | |
/// welll... at least bypass all of this and go down to rotate right/forward.... | |
return {forward:{x:0,y:0,z:1}, right:{x:1,y:0,z:0}, up:{x:0,y:1,z:0}, origin:{x:0,y:0,z:0 }}; | |
} | |
const sinQ = Math.sin( this.nL ); // sin/cos are the function of exp() | |
const cosQ = Math.cos( this.nL ); // sin/cos are the function of exp() | |
const nst = sinQ/this.nR; | |
const qx = q.x * nst; // normalizes the imaginary parts | |
const qy = q.y * nst; // set the sin of their composite angle as their total | |
const qz = q.z * nst; // output = 1(unit vector) * sin in x,y,z parts. | |
// V = v eHat_r + r dTh/dT * eHat_t + r * dphi/Dt * sinT * eHat_phi | |
const basis = { forward:null | |
, right:null | |
, up:null | |
, origin: { x:0, y:0, z:0 } }; | |
{ // this is the math-expanded version of the below; with primary terms instead of meta-constants | |
basis.up = { x : 2 * (sinQ / (q.nR * q.nR )) * ( q.y * q.x * sinQ - cosQ * q.z * q.nR ) | |
, y : 1 - 2 * sinQ*(sinQ / (q.nR * q.nR )) * ( q.z * q.z + q.x * q.x ) | |
, z : 2 * (sinQ / (q.nR * q.nR )) * ( q.z * q.y * sinQ + cosQ * q.x * q.nR ) }; | |
basis.right = { x : 1 - 2 * sinQ *( sinQ / (q.nR * q.nR )) * ( q.y * q.y + q.z * q.z ) | |
, y : 2 * ( sinQ / (q.nR * q.nR )) * ( q.y * q.x * sinQ - cosQ * q.z *q.nR ) | |
, z : 2 * ( sinQ / (q.nR * q.nR )) * ( q.x * q.z * sinQ - cosQ * q.y *q.nR ) }; | |
basis.forward = { x : 2 *(sinQ / (q.nR *q.nR)) * ( q.x * q.z * sinQ + cosQ * q.y * q.nR ) | |
, y : 2 *(sinQ / (q.nR *q.nR)) * ( q.z * q.y * sinQ - cosQ * q.x * q.nR ) | |
, z : 1 - 2 * sinQ *(sinQ / (q.nR *q.nR)) * ( q.x * q.x + q.y * q.y ) }; | |
} | |
/* | |
// s = sinQ, qw = cosQ : renamed | |
{ | |
const tx = 2 * ( -qz ); | |
const tz = 2 * (qx ); | |
basis.up = { x : qw * tx + qy * tz | |
, y : 1 + qz * tx - tz * qx | |
, z : qw * tz - tx * qy }; | |
} | |
{ | |
// for apply, this is cross(q,some point) | |
const ty = 2 * (qz); | |
const tz = 2 * (-qy); | |
basis.right = { x : 1 + ( qy * tz - ty * qz ) | |
, y : qw * ty + ( - tz * qx ) | |
, z : qw * tz + ( qx * ty ) }; | |
} | |
{ | |
// direct calculation of 'z' rotated by the vector. | |
const tx = 2 * ( qy ); | |
const ty = 2 * (-qx); | |
basis.forward = { x : qw * tx + ( - ty * qz ) | |
, y : qw * ty + ( qz * tx ) | |
, z : 1 + 0 + ( qx * ty - tx * qy ) }; | |
} | |
*/ | |
// return basis; } // This routine would end here... | |
// This multiplies the forward and right axis by some sin/cos of theta to rotate them around the Y. | |
// forward/right transform. | |
const dsin = Math.sin(theta); | |
const dcos = Math.cos(theta); | |
const v1 = { x:basis.right.x*dcos, y:basis.right.y*dcos, z:basis.right.z*dcos}; | |
const v2 = { x:basis.forward.x*dsin, y:basis.forward.y*dsin, z: basis.forward.z*dsin }; | |
basis.right.x = v1.x - v2.x; | |
basis.right.y = v1.y - v2.y; | |
basis.right.z = v1.z - v2.z; | |
const v3 = { x:basis.forward.x*dcos, y:basis.forward.y*dcos, z: basis.forward.z*dcos }; | |
const v4 = { x:basis.right.x*dsin, y:basis.right.y*dsin, z:basis.right.z*dsin}; | |
basis.forward.x = v3.x + v4.x; | |
basis.forward.y = v3.y + v4.y; | |
basis.forward.z = v3.z + v4.z; | |
// the above rotation is used only for substitution reference. | |
// ----------- This is the partial work for the following.... | |
// ([t]otal (step) ( [r]ight, [u]p, [f]orward ) | |
// t0f -> total step 0, forward | |
//const t0r = basis.right.x; | |
//const t1r = v1.x - v2.x; | |
//const t2r = basis.right.x*dcos - basis.forward.x*dsin; | |
const t3r = dcos - 2 * sinT *( sinT / (q.nR * q.nR )) * ( q.y * q.y + q.z * q.z ) * dcos | |
-( 2 *(sinT / (q.nR *q.nR)) * ( q.x * q.z * sinT + cosT * q.y * q.nR ) ) * dsin | |
//const t0u = basis.up.y; | |
const t1u = 1 - 2 * sinT*(sinT / (q.nR * q.nR )) * ( q.z * q.z + q.x * q.x ); | |
//const t0f = basis.forward.z; | |
//const t1f = v3.z + v4.z; | |
//const t2f = basis.forward.z*dcos + basis.right.z*dsin; | |
const t3f = dcos - 2 * sinT *(sinT / (q.nR *q.nR)) * ( q.x * q.x + q.y * q.y ) * dcos | |
+( 2 * ( sinT / (q.nR * q.nR )) * ( q.x * q.z * sinT - cosT * q.y *q.nR ) ) * dsin | |
// partial (sum of t3r, t3f, t1u ) | |
//const t1 = ( 2 - 2 * sinT *( sinT / (q.nR * q.nR )) * ( q.y * q.y + q.z * q.z - q.x * q.x - q.y * q.y ) * dcos | |
// - ( ( 2 *( sinT / (q.nR * q.nR )) * ( q.x * q.z * sinT + cosT * q.y * q.nR + q.x * q.z * sinT - cosT * q.y *q.nR ) ) ) * dsin | |
// + ( 1 - 2 * sinT*(sinT / (q.nR * q.nR )) * ( q.z * q.z + q.x * q.x ) ); | |
// (x-1) / 2... this part subtracted the 1, and divided by 2... and remove +q.y-q.y | |
const t1 = ( 1 - sinT *( sinT / (q.nR * q.nR )) * ( q.z * q.z - q.x * q.x ) ) * dcos | |
- ( sinT / (q.nR * q.nR )) * ( q.x * q.z * sinT + q.x * q.z * cosT ) * dsin | |
+( - sinT *( sinT / (q.nR * q.nR )) * ( q.z * q.z + q.x * q.x ) ); | |
// acos(t1) | |
//const angle1 = acos( ( 1 - sinT *( sinT / (q.nR * q.nR )) * ( q.z * q.z - q.x * q.x ) ) * dcos | |
// - ( sinT / (q.nR * q.nR )) * ( q.x * q.z * sinT + q.x * q.z * cosT ) * dsin | |
// - sinT *( sinT / (q.nR * q.nR )) * ( q.z * q.z + q.x * q.x ) ) | |
// ); | |
// this should be the complete expression for the bottom... change in angle. | |
const angle2 = acos( ( dcos - ( sinT*sinT / (q.nR * q.nR )) * ( | |
( q.z * q.z - q.x * q.x ) * dcos | |
- ( q.x * q.z * sinT + q.x * q.z * cosT ) * dsin | |
- ( q.z * q.z + q.x * q.x ) ) | |
); | |
// lnQuat.prototype.fromBasis = function( basis ) {... | |
// trace of the matrix is 2 * cosT + 1 | |
// tr(M)=2cos(theta)+1 . | |
const t = ( ( basis.right.x + basis.up.y + basis.forward.z ) - 1 )/2; // trace/total (expanded above) | |
const angle = Math.acos(t); // (expanded above) | |
/* | |
x = (R21 - R12)/sqrt((R21 - R12)^2+(R02 - R20)^2+(R10 - R01)^2); | |
y = (R02 - R20)/sqrt((R21 - R12)^2+(R02 - R20)^2+(R10 - R01)^2); | |
z = (R10 - R01)/sqrt((R21 - R12)^2+(R02 - R20)^2+(R10 - R01)^2); | |
*/ | |
/* | |
basis.forward.y -basis.up.z * basis.forward.y -basis.up.z ...... | |
( ( q.z * q.z * q.y * q.y * sinT * sinT - 2 * q.z * q.y * q.x * q.nR * sinT * cosT + q.x * q.x * q.nR * q.nR * cosT * cosT ) * dcos *dcos | |
+ ( q.y * q.y * q.x * q.x * sinT * sinT - 2 * q.y * q.x * sinT * cosT * q.z * q.nR + cosT * cosT * q.z * q.z * q.nR * q.nR ) * dsin * dsin | |
+ ( q.z * q.z * q.y * q.y * sinT * sinT + 2 * q.z * q.y * sinT * cosT * q.x * q.nR + cosT * cosT * q.x * q.x * q.nR * q.nR ) | |
+ 2 * ( q.z * q.y * sinT * q.y * q.x * sinT - q.z * q.y * sinT * cosT * q.z * q.nR - cosT * q.x * q.nR * q.y * q.x * sinT + cosT * q.x * q.nR * cosT * q.z * q.nR )*dsin *dcos | |
+ 2 * ( ( q.z * q.y * sinT - cosT * q.x * q.nR ) )*dcos * ( -q.z * q.y * sinT - cosT * q.x * q.nR ) | |
+ 2 * ( q.y * q.x * sinT - cosT * q.z * q.nR )*dsin * ( q.z * q.y * sinT + cosT * q.x * q.nR ) | |
*/ | |
const tmp = 1 /Math.sqrt((basis.forward.y -basis.up.z)*(basis.forward.y-basis.up.z) + (basis.right.z-basis.forward.x)*(basis.right.z-basis.forward.x) + (basis.up.x-basis.right.y)*(basis.up.x-basis.right.y)); | |
this.nx = (basis.up.z -basis.forward.y) *tmp; | |
this.ny = (basis.forward.x -basis.right.z ) *tmp; | |
this.nz = (basis.right.y -basis.up.x ) *tmp; | |
const lNorm = angle / (Math.abs(this.nx)+Math.abs(this.ny)+Math.abs(this.nz)); | |
this.x = this.nx * lNorm; | |
this.y = this.ny * lNorm; | |
this.z = this.nz * lNorm; | |
this.nx *= angle; | |
this.ny *= angle; | |
this.nz *= angle; | |
this.dirty = true; // update() later will fix nL and nR | |
return this; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment