UNPKG

bot18

Version:

A high-frequency cryptocurrency trading bot by Zenbot creator @carlos8f

658 lines (578 loc) 16.8 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>JSDoc: Source: quat.js</title> <script src="scripts/prettify/prettify.js"> </script> <script src="scripts/prettify/lang-css.js"> </script> <!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> </head> <body> <div id="main"> <h1 class="page-title">Source: quat.js</h1> <section> <article> <pre class="prettyprint source linenums"><code>import * as glMatrix from "./common.js" import * as mat3 from "./mat3.js" import * as vec3 from "./vec3.js" import * as vec4 from "./vec4.js" /** * Quaternion * @module quat */ /** * Creates a new identity quat * * @returns {quat} a new quaternion */ export function create() { let out = new glMatrix.ARRAY_TYPE(4); out[0] = 0; out[1] = 0; out[2] = 0; out[3] = 1; return out; } /** * Set a quat to the identity quaternion * * @param {quat} out the receiving quaternion * @returns {quat} out */ export function identity(out) { out[0] = 0; out[1] = 0; out[2] = 0; out[3] = 1; return out; } /** * Sets a quat from the given angle and rotation axis, * then returns it. * * @param {quat} out the receiving quaternion * @param {vec3} axis the axis around which to rotate * @param {Number} rad the angle in radians * @returns {quat} out **/ export function setAxisAngle(out, axis, rad) { rad = rad * 0.5; let s = Math.sin(rad); out[0] = s * axis[0]; out[1] = s * axis[1]; out[2] = s * axis[2]; out[3] = Math.cos(rad); return out; } /** * Gets the rotation axis and angle for a given * quaternion. If a quaternion is created with * setAxisAngle, this method will return the same * values as providied in the original parameter list * OR functionally equivalent values. * Example: The quaternion formed by axis [0, 0, 1] and * angle -90 is the same as the quaternion formed by * [0, 0, 1] and 270. This method favors the latter. * @param {vec3} out_axis Vector receiving the axis of rotation * @param {quat} q Quaternion to be decomposed * @return {Number} Angle, in radians, of the rotation */ export function getAxisAngle(out_axis, q) { let rad = Math.acos(q[3]) * 2.0; let s = Math.sin(rad / 2.0); if (s != 0.0) { out_axis[0] = q[0] / s; out_axis[1] = q[1] / s; out_axis[2] = q[2] / s; } else { // If s is zero, return any axis (no rotation - axis does not matter) out_axis[0] = 1; out_axis[1] = 0; out_axis[2] = 0; } return rad; } /** * Multiplies two quat's * * @param {quat} out the receiving quaternion * @param {quat} a the first operand * @param {quat} b the second operand * @returns {quat} out */ export function multiply(out, a, b) { let ax = a[0], ay = a[1], az = a[2], aw = a[3]; let bx = b[0], by = b[1], bz = b[2], bw = b[3]; out[0] = ax * bw + aw * bx + ay * bz - az * by; out[1] = ay * bw + aw * by + az * bx - ax * bz; out[2] = az * bw + aw * bz + ax * by - ay * bx; out[3] = aw * bw - ax * bx - ay * by - az * bz; return out; } /** * Rotates a quaternion by the given angle about the X axis * * @param {quat} out quat receiving operation result * @param {quat} a quat to rotate * @param {number} rad angle (in radians) to rotate * @returns {quat} out */ export function rotateX(out, a, rad) { rad *= 0.5; let ax = a[0], ay = a[1], az = a[2], aw = a[3]; let bx = Math.sin(rad), bw = Math.cos(rad); out[0] = ax * bw + aw * bx; out[1] = ay * bw + az * bx; out[2] = az * bw - ay * bx; out[3] = aw * bw - ax * bx; return out; } /** * Rotates a quaternion by the given angle about the Y axis * * @param {quat} out quat receiving operation result * @param {quat} a quat to rotate * @param {number} rad angle (in radians) to rotate * @returns {quat} out */ export function rotateY(out, a, rad) { rad *= 0.5; let ax = a[0], ay = a[1], az = a[2], aw = a[3]; let by = Math.sin(rad), bw = Math.cos(rad); out[0] = ax * bw - az * by; out[1] = ay * bw + aw * by; out[2] = az * bw + ax * by; out[3] = aw * bw - ay * by; return out; } /** * Rotates a quaternion by the given angle about the Z axis * * @param {quat} out quat receiving operation result * @param {quat} a quat to rotate * @param {number} rad angle (in radians) to rotate * @returns {quat} out */ export function rotateZ(out, a, rad) { rad *= 0.5; let ax = a[0], ay = a[1], az = a[2], aw = a[3]; let bz = Math.sin(rad), bw = Math.cos(rad); out[0] = ax * bw + ay * bz; out[1] = ay * bw - ax * bz; out[2] = az * bw + aw * bz; out[3] = aw * bw - az * bz; return out; } /** * Calculates the W component of a quat from the X, Y, and Z components. * Assumes that quaternion is 1 unit in length. * Any existing W component will be ignored. * * @param {quat} out the receiving quaternion * @param {quat} a quat to calculate W component of * @returns {quat} out */ export function calculateW(out, a) { let x = a[0], y = a[1], z = a[2]; out[0] = x; out[1] = y; out[2] = z; out[3] = Math.sqrt(Math.abs(1.0 - x * x - y * y - z * z)); return out; } /** * Performs a spherical linear interpolation between two quat * * @param {quat} out the receiving quaternion * @param {quat} a the first operand * @param {quat} b the second operand * @param {Number} t interpolation amount, in the range [0-1], between the two inputs * @returns {quat} out */ export function slerp(out, a, b, t) { // benchmarks: // http://jsperf.com/quaternion-slerp-implementations let ax = a[0], ay = a[1], az = a[2], aw = a[3]; let bx = b[0], by = b[1], bz = b[2], bw = b[3]; let omega, cosom, sinom, scale0, scale1; // calc cosine cosom = ax * bx + ay * by + az * bz + aw * bw; // adjust signs (if necessary) if ( cosom &lt; 0.0 ) { cosom = -cosom; bx = - bx; by = - by; bz = - bz; bw = - bw; } // calculate coefficients if ( (1.0 - cosom) > 0.000001 ) { // standard case (slerp) omega = Math.acos(cosom); sinom = Math.sin(omega); scale0 = Math.sin((1.0 - t) * omega) / sinom; scale1 = Math.sin(t * omega) / sinom; } else { // "from" and "to" quaternions are very close // ... so we can do a linear interpolation scale0 = 1.0 - t; scale1 = t; } // calculate final values out[0] = scale0 * ax + scale1 * bx; out[1] = scale0 * ay + scale1 * by; out[2] = scale0 * az + scale1 * bz; out[3] = scale0 * aw + scale1 * bw; return out; } /** * Calculates the inverse of a quat * * @param {quat} out the receiving quaternion * @param {quat} a quat to calculate inverse of * @returns {quat} out */ export function invert(out, a) { let a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3]; let dot = a0*a0 + a1*a1 + a2*a2 + a3*a3; let invDot = dot ? 1.0/dot : 0; // TODO: Would be faster to return [0,0,0,0] immediately if dot == 0 out[0] = -a0*invDot; out[1] = -a1*invDot; out[2] = -a2*invDot; out[3] = a3*invDot; return out; } /** * Calculates the conjugate of a quat * If the quaternion is normalized, this function is faster than quat.inverse and produces the same result. * * @param {quat} out the receiving quaternion * @param {quat} a quat to calculate conjugate of * @returns {quat} out */ export function conjugate(out, a) { out[0] = -a[0]; out[1] = -a[1]; out[2] = -a[2]; out[3] = a[3]; return out; } /** * Creates a quaternion from the given 3x3 rotation matrix. * * NOTE: The resultant quaternion is not normalized, so you should be sure * to renormalize the quaternion yourself where necessary. * * @param {quat} out the receiving quaternion * @param {mat3} m rotation matrix * @returns {quat} out * @function */ export function fromMat3(out, m) { // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes // article "Quaternion Calculus and Fast Animation". let fTrace = m[0] + m[4] + m[8]; let fRoot; if ( fTrace > 0.0 ) { // |w| > 1/2, may as well choose w > 1/2 fRoot = Math.sqrt(fTrace + 1.0); // 2w out[3] = 0.5 * fRoot; fRoot = 0.5/fRoot; // 1/(4w) out[0] = (m[5]-m[7])*fRoot; out[1] = (m[6]-m[2])*fRoot; out[2] = (m[1]-m[3])*fRoot; } else { // |w| &lt;= 1/2 let i = 0; if ( m[4] > m[0] ) i = 1; if ( m[8] > m[i*3+i] ) i = 2; let j = (i+1)%3; let k = (i+2)%3; fRoot = Math.sqrt(m[i*3+i]-m[j*3+j]-m[k*3+k] + 1.0); out[i] = 0.5 * fRoot; fRoot = 0.5 / fRoot; out[3] = (m[j*3+k] - m[k*3+j]) * fRoot; out[j] = (m[j*3+i] + m[i*3+j]) * fRoot; out[k] = (m[k*3+i] + m[i*3+k]) * fRoot; } return out; } /** * Creates a quaternion from the given euler angle x, y, z. * * @param {quat} out the receiving quaternion * @param {x} Angle to rotate around X axis in degrees. * @param {y} Angle to rotate around Y axis in degrees. * @param {z} Angle to rotate around Z axis in degrees. * @returns {quat} out * @function */ export function fromEuler(out, x, y, z) { let halfToRad = 0.5 * Math.PI / 180.0; x *= halfToRad; y *= halfToRad; z *= halfToRad; let sx = Math.sin(x); let cx = Math.cos(x); let sy = Math.sin(y); let cy = Math.cos(y); let sz = Math.sin(z); let cz = Math.cos(z); out[0] = sx * cy * cz - cx * sy * sz; out[1] = cx * sy * cz + sx * cy * sz; out[2] = cx * cy * sz - sx * sy * cz; out[3] = cx * cy * cz + sx * sy * sz; return out; } /** * Returns a string representation of a quatenion * * @param {quat} a vector to represent as a string * @returns {String} string representation of the vector */ export function str(a) { return 'quat(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')'; } /** * Creates a new quat initialized with values from an existing quaternion * * @param {quat} a quaternion to clone * @returns {quat} a new quaternion * @function */ export const clone = vec4.clone; /** * Creates a new quat initialized with the given values * * @param {Number} x X component * @param {Number} y Y component * @param {Number} z Z component * @param {Number} w W component * @returns {quat} a new quaternion * @function */ export const fromValues = vec4.fromValues; /** * Copy the values from one quat to another * * @param {quat} out the receiving quaternion * @param {quat} a the source quaternion * @returns {quat} out * @function */ export const copy = vec4.copy; /** * Set the components of a quat to the given values * * @param {quat} out the receiving quaternion * @param {Number} x X component * @param {Number} y Y component * @param {Number} z Z component * @param {Number} w W component * @returns {quat} out * @function */ export const set = vec4.set; /** * Adds two quat's * * @param {quat} out the receiving quaternion * @param {quat} a the first operand * @param {quat} b the second operand * @returns {quat} out * @function */ export const add = vec4.add; /** * Alias for {@link quat.multiply} * @function */ export const mul = multiply; /** * Scales a quat by a scalar number * * @param {quat} out the receiving vector * @param {quat} a the vector to scale * @param {Number} b amount to scale the vector by * @returns {quat} out * @function */ export const scale = vec4.scale; /** * Calculates the dot product of two quat's * * @param {quat} a the first operand * @param {quat} b the second operand * @returns {Number} dot product of a and b * @function */ export const dot = vec4.dot; /** * Performs a linear interpolation between two quat's * * @param {quat} out the receiving quaternion * @param {quat} a the first operand * @param {quat} b the second operand * @param {Number} t interpolation amount, in the range [0-1], between the two inputs * @returns {quat} out * @function */ export const lerp = vec4.lerp; /** * Calculates the length of a quat * * @param {quat} a vector to calculate length of * @returns {Number} length of a */ export const length = vec4.length; /** * Alias for {@link quat.length} * @function */ export const len = length; /** * Calculates the squared length of a quat * * @param {quat} a vector to calculate squared length of * @returns {Number} squared length of a * @function */ export const squaredLength = vec4.squaredLength; /** * Alias for {@link quat.squaredLength} * @function */ export const sqrLen = squaredLength; /** * Normalize a quat * * @param {quat} out the receiving quaternion * @param {quat} a quaternion to normalize * @returns {quat} out * @function */ export const normalize = vec4.normalize; /** * Returns whether or not the quaternions have exactly the same elements in the same position (when compared with ===) * * @param {quat} a The first quaternion. * @param {quat} b The second quaternion. * @returns {Boolean} True if the vectors are equal, false otherwise. */ export const exactEquals = vec4.exactEquals; /** * Returns whether or not the quaternions have approximately the same elements in the same position. * * @param {quat} a The first vector. * @param {quat} b The second vector. * @returns {Boolean} True if the vectors are equal, false otherwise. */ export const equals = vec4.equals; /** * Sets a quaternion to represent the shortest rotation from one * vector to another. * * Both vectors are assumed to be unit length. * * @param {quat} out the receiving quaternion. * @param {vec3} a the initial vector * @param {vec3} b the destination vector * @returns {quat} out */ export const rotationTo = (function() { let tmpvec3 = vec3.create(); let xUnitVec3 = vec3.fromValues(1,0,0); let yUnitVec3 = vec3.fromValues(0,1,0); return function(out, a, b) { let dot = vec3.dot(a, b); if (dot &lt; -0.999999) { vec3.cross(tmpvec3, xUnitVec3, a); if (vec3.len(tmpvec3) &lt; 0.000001) vec3.cross(tmpvec3, yUnitVec3, a); vec3.normalize(tmpvec3, tmpvec3); setAxisAngle(out, tmpvec3, Math.PI); return out; } else if (dot > 0.999999) { out[0] = 0; out[1] = 0; out[2] = 0; out[3] = 1; return out; } else { vec3.cross(tmpvec3, a, b); out[0] = tmpvec3[0]; out[1] = tmpvec3[1]; out[2] = tmpvec3[2]; out[3] = 1 + dot; return normalize(out, out); } }; })(); /** * Performs a spherical linear interpolation with two control points * * @param {quat} out the receiving quaternion * @param {quat} a the first operand * @param {quat} b the second operand * @param {quat} c the third operand * @param {quat} d the fourth operand * @param {Number} t interpolation amount, in the range [0-1], between the two inputs * @returns {quat} out */ export const sqlerp = (function () { let temp1 = create(); let temp2 = create(); return function (out, a, b, c, d, t) { slerp(temp1, a, d, t); slerp(temp2, b, c, t); slerp(out, temp1, temp2, 2 * t * (1 - t)); return out; }; }()); /** * Sets the specified quaternion with values corresponding to the given * axes. Each axis is a vec3 and is expected to be unit length and * perpendicular to all other specified axes. * * @param {vec3} view the vector representing the viewing direction * @param {vec3} right the vector representing the local "right" direction * @param {vec3} up the vector representing the local "up" direction * @returns {quat} out */ export const setAxes = (function() { let matr = mat3.create(); return function(out, view, right, up) { matr[0] = right[0]; matr[3] = right[1]; matr[6] = right[2]; matr[1] = up[0]; matr[4] = up[1]; matr[7] = up[2]; matr[2] = -view[0]; matr[5] = -view[1]; matr[8] = -view[2]; return normalize(out, fromMat3(out, matr)); }; })(); </code></pre> </article> </section> </div> <nav> <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-glMatrix.html">glMatrix</a></li><li><a href="module-mat2.html">mat2</a></li><li><a href="module-mat2d.html">mat2d</a></li><li><a href="module-mat3.html">mat3</a></li><li><a href="module-mat4.html">mat4</a></li><li><a href="module-quat.html">quat</a></li><li><a href="module-quat2.html">quat2</a></li><li><a href="module-vec2.html">vec2</a></li><li><a href="module-vec3.html">vec3</a></li><li><a href="module-vec4.html">vec4</a></li></ul> </nav> <br class="clear"> <footer> Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Fri May 18 2018 11:25:14 GMT+0100 (BST) </footer> <script> prettyPrint(); </script> <script src="scripts/linenumber.js"> </script> </body> </html>