packages feed

easytensor-0.3.1.0: src-ghcjs/Numeric/Quaternion/Quaternion.js

function h$easytensor_rotScale(quat, vec) {
    'use strict';
    var i = quat[0], j = quat[1], k = quat[2], t = quat[3];
    var x = vec[0], y = vec[1], z = vec[2];
    var l = t*t - i*i - j*j - k*k;
    var d = 2*(i*x + j*y + k*z);
    t *= 2;
    return [ l*x + d*i + t*(z*j - y*k)
           , l*y + d*j + t*(x*k - z*i)
           , l*z + d*k + t*(y*i - x*j)
           ];
}

function h$easytensor_qArg(quat) {
    'use strict';
    return Math.atan2( Math.hypot(quat[0],quat[1],quat[2]) , quat[3] ) * 2 ;
}

function h$easytensor_getRotScale(a, b) {
    'use strict';
    if (b[0] === 0 && b[1] === 0 && b[2] === 0) { return [0,0,0,0];}
    if (a[0] === 0 && a[1] === 0 && a[2] === 0) { return [Infinity,Infinity,Infinity,Infinity];}
    var t = h$easytensor_cross(a, b);
    var ma = Math.hypot(a[0],a[1],a[2]);
    var mb = Math.hypot(b[0],b[1],b[2]);
    var dot = a[0]*b[0]+a[1]*b[1]+a[2]*b[2];
    if (t[0] === 0 && t[1] === 0 && t[2] === 0) {
        if (dot > 0) {return [0,0,0,Math.sqrt(mb/ma)];}
        else         {return [0,0,Math.sqrt(mb/ma),0];}
    }
    var c = Math.sqrt(ma*mb + dot);
    ma *= Math.SQRT2;
    return [ t[0]/(ma*c)
           , t[1]/(ma*c)
           , t[2]/(ma*c)
           , c/ma
           ];
}

function h$easytensor_axisRotation(axis, a) {
    'use strict';
    if (axis[0] === 0 && axis[1] === 0 && axis[2] === 0) { return [0,0,0,1];}
    var c = Math.cos(a*0.5), s = Math.sin(a*0.5) / Math.hypot(axis[0],axis[1],axis[2]);
    return [ axis[0]*s, axis[1]*s, axis[2]*s, c];
}

function h$easytensor_qfromMatrix33(m) {
    'use strict';
    var d = Math.cbrt(
          m[0]*(m[4]*m[8]-m[5]*m[7])
        - m[1]*(m[3]*m[8]-m[5]*m[6])
        + m[2]*(m[3]*m[7]-m[4]*m[6]));
    return [ Math.sqrt(Math.max( 0, d + m[0] - m[4] - m[8] )) * Math.sign(m[5] - m[7]) * 0.5
           , Math.sqrt(Math.max( 0, d - m[0] + m[4] - m[8] )) * Math.sign(m[6] - m[2]) * 0.5
           , Math.sqrt(Math.max( 0, d - m[0] - m[4] + m[8] )) * Math.sign(m[1] - m[3]) * 0.5
           , Math.sqrt(Math.max( 0, d + m[0] + m[4] + m[8] )) * 0.5 ];
}

function h$easytensor_qfromMatrix44(m) {
    'use strict';
    var d = Math.cbrt(
          m[0]*(m[5]*m[10]-m[6]*m[9])
        - m[1]*(m[4]*m[10]-m[6]*m[8])
        + m[2]*(m[4]*m[ 9]-m[5]*m[8]));
    return [ Math.sqrt(Math.max( 0, d + m[0] - m[5] - m[10] )) * Math.sign(m[6] - m[9]) * 0.5 / m[15]
           , Math.sqrt(Math.max( 0, d - m[0] + m[5] - m[10] )) * Math.sign(m[8] - m[2]) * 0.5 / m[15]
           , Math.sqrt(Math.max( 0, d - m[0] - m[5] + m[10] )) * Math.sign(m[1] - m[4]) * 0.5 / m[15]
           , Math.sqrt(Math.max( 0, d + m[0] + m[5] + m[10] )) * 0.5 / m[15] ];
}

function h$easytensor_qtoMatrix33(quat) {
    'use strict';
    var x = quat[0], y = quat[1], z = quat[2], w = quat[3];
    var w2 = w*w;
    if (x === 0 && y === 0 && z === 0) {
        return [w2,0,0
               ,0,w2,0
               ,0,0,w2];
    }
    var x2 = x*x, y2 = y*y, z2 = z*z;
    var l2 = x2+y2+z2+w2;
    return [ l2 - 2*(z2 + y2),    2*(x*y + z*w),    2*(x*z - y*w)
           ,    2*(x*y - z*w), l2 - 2*(z2 + x2),    2*(y*z + x*w)
           ,    2*(x*z + y*w),    2*(y*z - x*w), l2 - 2*(y2 + x2) ];
}

function h$easytensor_qtoMatrix44(quat) {
    'use strict';
    var x = quat[0], y = quat[1], z = quat[2], w = quat[3];
    var w2 = w*w;
    if (x === 0 && y === 0 && z === 0) {
        return [w2,0,0,0
               ,0,w2,0,0
               ,0,0,w2,0
               ,0,0,0,1];
    }
    var x2 = x*x, y2 = y*y, z2 = z*z;
    var l2 = x2+y2+z2+w2;
    return [ l2 - 2*(z2 + y2),    2*(x*y + z*w),    2*(x*z - y*w), 0
           ,    2*(x*y - z*w), l2 - 2*(z2 + x2),    2*(y*z + x*w), 0
           ,    2*(x*z + y*w),    2*(y*z - x*w), l2 - 2*(y2 + x2), 0
           , 0, 0, 0, 1];
}

function h$easytensor_qrecip(q) {
    'use strict';
    var c = -1 / (q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3]);
    return [q[0]*c,q[1]*c,q[2]*c,-q[3]*c];
}

function h$easytensor_qexp(q) {
    'use strict';
    var mv = Math.hypot(q[0],q[1],q[2]), et = Math.exp(q[3]);
    if(mv === 0) {return [0,0,0,et];}
    var l = et * Math.sin(mv) / mv;
    return [q[0]*l,q[1]*l,q[2]*l,et*Math.cos(mv)];
}
function h$easytensor_qlog(q) {
    'use strict';
    var mv = q[0]*q[0] + q[1]*q[1] + q[2]*q[2];
    if(mv === 0) {
      if(q[3] >= 0){
        return [0,0,0,Math.log(q[3])];
      } else {
        return [Math.PI,0,0,Math.log(-q[3])];
      }
    }
    var mq = Math.sqrt(mv + q[3]*q[3]);
    mv = Math.sqrt(mv);
    var l = Math.atan2( mv, q[3] ) / mv;
    return [q[0]*l,q[1]*l,q[2]*l,Math.log(mq)];
}
function h$easytensor_qsqrt(q) {
    'use strict';
    var mv = q[0]*q[0] + q[1]*q[1] + q[2]*q[2];
    if(mv === 0) {
      if(q[3] >= 0){
        return [0,0,0,Math.sqrt(q[3])];
      } else {
        return [Math.sqrt(-q[3]),0,0,0];
      }
    }
    var l = Math.sqrt(mv + q[3]*q[3]);
    var l2 = Math.sqrt(l);
    var tq = q[3] / (l * 2);
    var sina = Math.sqrt(0.5 - tq) * l2 / Math.sqrt(mv);
    return [q[0]*sina,q[1]*sina,q[2]*sina,Math.sqrt(0.5 + tq) * l2];
}

// A good tutorial on complex number trigonometric functions is available here
//  http://www.milefoot.com/math/complex/functionsofi.htm
// I extend it to complex numbers by replacing complex i with quaternion vector ijk

function h$easytensor_qsin(q) {
    'use strict';
    var mv = q[0]*q[0] + q[1]*q[1] + q[2]*q[2];
    if(mv === 0) {return [0,0,0,Math.sin(q[3])];}
    mv = Math.sqrt(mv);
    var l = Math.cos(q[3]) * Math.sinh(mv) / mv;
    return [q[0]*l,q[1]*l,q[2]*l, Math.sin(q[3])*Math.cosh(mv)];
}
function h$easytensor_qcos(q) {
    'use strict';
    var mv = q[0]*q[0] + q[1]*q[1] + q[2]*q[2];
    if(mv === 0) {return [0,0,0,Math.cos(q[3])];}
    mv = Math.sqrt(mv);
    var l = - Math.sin(q[3]) * Math.sinh(mv) / mv;
    return [q[0]*l,q[1]*l,q[2]*l, Math.cos(q[3])*Math.cosh(mv)];
}
function h$easytensor_qtan(q) {
    'use strict';
    var mv = q[0]*q[0] + q[1]*q[1] + q[2]*q[2];
    if(mv === 0) {return [0,0,0,Math.tan(q[3])];}
    mv = Math.sqrt(mv);
    var chv = Math.cosh(mv), shv = Math.sinh(mv), ct = Math.cos(q[3]), st = Math.sin(q[3]);
    var cq = 1 / (ct*ct*chv*chv + st*st*shv*shv);
    var l = chv * shv * cq / mv;
    return [q[0]*l,q[1]*l,q[2]*l, ct * st * cq];
}
function h$easytensor_qsinh(q) {
    'use strict';
    var mv = q[0]*q[0] + q[1]*q[1] + q[2]*q[2];
    if(mv === 0) {return [0,0,0,Math.sinh(q[3])];}
    mv = Math.sqrt(mv);
    var l = Math.cosh(q[3]) * Math.sin(mv) / mv;
    return [q[0]*l,q[1]*l,q[2]*l, Math.sinh(q[3])*Math.cos(mv)];
}
function h$easytensor_qcosh(q) {
    'use strict';
    var mv = q[0]*q[0] + q[1]*q[1] + q[2]*q[2];
    if(mv === 0) {return [0,0,0,Math.cosh(q[3])];}
    mv = Math.sqrt(mv);
    var l = Math.sinh(q[3]) * Math.sin(mv) / mv;
    return [q[0]*l,q[1]*l,q[2]*l, Math.cosh(q[3])*Math.cos(mv)];
}
function h$easytensor_qtanh(q) {
    'use strict';
    var mv = q[0]*q[0] + q[1]*q[1] + q[2]*q[2];
    if(mv === 0) {return [0,0,0,Math.tanh(q[3])];}
    mv = Math.sqrt(mv);
    var cv = Math.cos(mv), sv = Math.sin(mv), cht = Math.cosh(q[3]), sht = Math.sinh(q[3]);
    var cq = 1 / (cht*cht*cv*cv + sht*sht*sv*sv);
    var l = cv * sv * cq / mv;
    return [q[0]*l,q[1]*l,q[2]*l, cht * sht * cq];
}