/** * @fileOverview Math */ /** * The SpiderGL.Math namespace. * * @namespace The SpiderGL.Math namespace. */ SpiderGL = {}; SpiderGL.Math = { }; // constants /*---------------------------------------------------------*/ /** * Scale factor for degrees to radians conversion. * It is equal to PI / 180. * * @constant * * @type number */ SpiderGL.Math.DEG_TO_RAD = (Math.PI / 180.0); /** * Alias for Math.E. * * @constant * * @type number */ SpiderGL.Math.E = Math.E; /** * Alias for Math.LN2. * * @constant * * @type number */ SpiderGL.Math.LN2 = Math.LN2; /** * Alias for Math.LN10. * * @constant * * @type number */ SpiderGL.Math.LN10 = Math.LN10; /** * Alias for Math.LOG2E. * * @constant * * @type number */ SpiderGL.Math.LOG2E = Math.LOG2E; /** * Alias for Math.LOG10E. * * @constant * * @type number */ SpiderGL.Math.LOG10E = Math.LOG10E; /** * Alias for Math.PI. * * @constant * * @type number */ SpiderGL.Math.PI = Math.PI; /** * Scale factor for radians to degrees conversion. * It is equal to 180 / PI. * * @constant * * @type number */ SpiderGL.Math.RAD_TO_DEG = (180.0 / Math.PI); /** * Alias for Math.SQRT2. * * @constant * * @type number */ SpiderGL.Math.SQRT2 = Math.SQRT2; /** * Alias for Number.MAX_VALUE. * * @constant * * @type number */ SpiderGL.Math.MAX_VALUE = Number.MAX_VALUE; /** * Alias for Number.MIN_VALUE. * * @constant * * @type number */ SpiderGL.Math.MIN_VALUE = Number.MIN_VALUE; /** * Alias for SpiderGL.Math.MAX_VALUE. * * @constant * * @type number */ SpiderGL.Math.MAX_NUMBER = SpiderGL.Math.MAX_VALUE; /** * Alias for -SpiderGL.Math.MAX_VALUE. * * @constant * * @type number */ SpiderGL.Math.MIN_NUMBER = -SpiderGL.Math.MAX_VALUE; /** * Alias for Number.NaN. * * @constant * * @type number */ SpiderGL.Math.NAN = Number.NaN; /** * Alias for global Infinity. * * @constant * * @type number */ SpiderGL.Math.INFINITY = Infinity; /*---------------------------------------------------------*/ // functions on scalars /*---------------------------------------------------------*/ /** * Alias for Math.abs. * * @param {number} x A number. * * @returns {number} The absolute value of x. */ SpiderGL.Math.abs = function (x) { return Math.abs(x); } /** * Alias for Math.acos. * * @param {number} x The input cosine. * * @returns {number} The arccosine of x, in radians. */ SpiderGL.Math.acos = function (x) { return Math.acos(x); } /** * Alias for Math.asin. * * @param {number} x The input sine. * * @returns {number} The arcsine of x, in radians. */ SpiderGL.Math.asin = function (x) { return Math.asin(x); } /** * Alias for Math.atan2. * * @param {number} x The input number. * * @returns {number} The arctangent of x as a numeric value between -PI/2 and PI/2 radians. */ SpiderGL.Math.atan = function (x) { return Math.atan(x); } /** * Alias for Math.atan2. * * @param {number} y A number. * @param {number} x A number. * * @returns {number} The the arctangent of the quotient of its arguments as a numeric value between PI and -PI. */ SpiderGL.Math.atan2 = function (y, x) { return Math.atan2(y, x); } /** * Alias for Math.ceil. * * @param {number} x The input number. * * @returns {number} x rounded upwards to the nearest integer. */ SpiderGL.Math.ceil = function (x) { return Math.ceil(x); } /** * Clamps a number over a range. * * @param {number} x The number to clamp. * @param {number} min The lower bound. * @param {number} max The upper bound. * * @returns {number} min if x < min, max if x > max, x otherwise. */ SpiderGL.Math.clamp = function (x, min, max) { return ((x <= min) ? (min) : ((x >= max) ? (max) : (x))); } /** * Alias for Math.cos. * * @param {number} x The input angle, in radians. * * @returns {number} The cosine of x. */ SpiderGL.Math.cos = function (x) { return Math.cos(x); } /** * Converts degrees to radians. * * @param {number} x The input angle, in degrees. * * @returns {number} x in radians. */ SpiderGL.Math.degToRad = function (x) { return (x * SpiderGL.Math.DEG_TO_RAD); } /** * Alias for Math.exp. * * @param {number} x The input number. * * @returns {number} E raised to x. */ SpiderGL.Math.exp = function (x) { return Math.exp(x); } /** * Alias for Math.floor. * * @param {number} x The input number. * * @returns {number} x rounded downwards to the nearest integer. */ SpiderGL.Math.floor = function (x) { return Math.floor(x); } /** * Linear interpolation between two numbers. * * @param {number} x The start interpolation bound. * @param {number} y The stop interpolation bound. * @param {number} t The interpolation factor, between 0 and 1.. * * @returns {number} The interpolated value (1-t)*x + t*y. */ SpiderGL.Math.lerp = function (x, y, t) { return x + t * (y - x); } /** * Alias for Math.log. * Same as {@link SpiderGL.Math.log}. * * @param {number} x The input number. * * @returns {number} The natural logarithm (base E) of x. */ SpiderGL.Math.ln = function (x) { return Math.log(x); } /** * Alias for Math.log. * * @param {number} x The input number. * * @returns {number} The natural logarithm (base E) of x. */ SpiderGL.Math.log = function (x) { return Math.log(x); } /** * Logarithm base 2. * * @param {number} x The input number. * * @returns {number} The base 2 logarithm of x. */ SpiderGL.Math.log2 = function (x) { return (SpiderGL.Math.log(x) / SpiderGL.Math.LN2); } /** * Logarithm base 10. * * @param {number} x The input number. * * @returns {number} The base 10 logarithm of x. */ SpiderGL.Math.log10 = function (x) { return (SpiderGL.Math.log(x) / SpiderGL.Math.LN10); } /** * Alias for Math.max. * * @param {number} args Variable number of arguments * * @returns {number} The number with the highest value. * * @example * var x = SpiderGL.Math.max(3, 1.56, 2.1); // x == 3 */ SpiderGL.Math.max = function (args) { return Math.max.apply(Math, arguments); } /** * Alias for Math.min. * * @param {number} args Variable number of arguments * * @returns {number} The number with the lowest value. * * @example * var x = SpiderGL.Math.min(3, 1.56, 2.1); // x == 1.56 */ SpiderGL.Math.min = function (args) { return Math.min.apply(Math, arguments); } /** * Alias for Math.pow. * * @param {number} x The base number. * @param {number} x The exponent number. * * @returns {number} The value of x to the power of y. */ SpiderGL.Math.pow = function (x, y) { return Math.pow(x, y); } /** * Converts radians to degrees. * * @param {number} x The input angle, in radians. * * @returns {number} x in degrees. */ SpiderGL.Math.radToDeg = function (x) { return (x * SpiderGL.Math.RAD_TO_DEG); } /** * Alias for Math.random. * * @returns {number} A random number between 0.0 and 1.0, inclusive. */ SpiderGL.Math.random = function () { return Math.random(); } /** * Alias for SpiderGL.Math.random. * * @returns {number} A random number between 0.0 and 1.0, inclusive. */ SpiderGL.Math.random01 = function () { return SpiderGL.Math.random(); } /** * Generates a random number between -1.0 and 1.0. * * @returns {number} A random number between -1.0 and 1.0, inclusive. */ SpiderGL.Math.random11 = function () { return (SpiderGL.Math.random() * 2 - 1); } /** * Generates a random number between a and b. * * @param {number} min The range low end-point. * @param {number} max The range high end-point. * * @returns {number} A random number between min and max, inclusive. */ SpiderGL.Math.randomRange = function (min, max) { return (min + SpiderGL.Math.random() * (max - min)); } /** * Alias for Math.round. * * @param {number} x The input number. * * @returns {number} x rounded to the nearest integer. * * @example * var a = SpiderGL.Math.round( 3); // a == 3 * var b = SpiderGL.Math.round( -4); // b == -4 * var c = SpiderGL.Math.round( 7.21); // c == 7 * var d = SpiderGL.Math.round( 7.56); // d == 8 * var e = SpiderGL.Math.round(-7.56); // e == -8 * var f = SpiderGL.Math.round(-7.21); // f == -7 */ SpiderGL.Math.round = function (x) { return Math.sqrt(x); } /** * Alias for Math.sin. * * @param {number} x The input angle, in radians. * * @returns {number} The sine of x. */ SpiderGL.Math.sin = function (x) { return Math.sin(x); } /** * Alias for Math.sqrt. * * @param {number} x The input number. * * @returns {number} The square root of x. */ SpiderGL.Math.sqrt = function (x) { return Math.sqrt(x); } /** * Alias for Math.tan. * * @param {number} x The input angle, in radians. * * @returns {number} The tangent of x. */ SpiderGL.Math.tan = function (x) { return Math.tan(x); } /*---------------------------------------------------------*/ // 2-dimensional vector /*---------------------------------------------------------*/ /** * The SpiderGL.Math.Vec2 namespace. * The provided functions operate on 2-dimensional vectors, represented as standard JavaScript arrays of length 2. * In general, vectors are considered as column vectors. * * @namespace The SpiderGL.Math.Vec2 namespace defines operations on 2-dimensional vectors. */ SpiderGL.Math.Vec2 = { }; /** * Duplicates the input 2-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 2-dimensional vector r, where r[i] = v[i] (same as v.slice(0, 2)). */ SpiderGL.Math.Vec2.dup = function (v) { return v.slice(0, 2); } /** * Creates a 2-dimensional vector initialized with a scalar. * * @param {number} s The input scalar. * * @returns {array} A 2-dimensional vector r, where r[i] = s. */ SpiderGL.Math.Vec2.scalar = function (s) { return [s, s]; } /** * Creates a 2-dimensional vector initialized with zero. * * @returns {array} A 2-dimensional vector r, where r[i] = 0. */ SpiderGL.Math.Vec2.zero = function () { return [0, 0]; } /** * Creates a 2-dimensional vector initialized with one. * * @returns {array} A 2-dimensional vector r, where r[i] = 1.0. */ SpiderGL.Math.Vec2.one = function () { return [1, 1]; } /** * Creates a 2-dimensional vector initialized with SpiderGL.Math.MAX_NUMBER. * * @returns {array} A 2-dimensional vector r, where r[i] = SpiderGL.Math.MAX_NUMBER. */ SpiderGL.Math.Vec2.maxNumber = function () { return [SpiderGL.Math.MAX_NUMBER, SpiderGL.Math.MAX_NUMBER]; } /** * Creates a 2-dimensional vector initialized with SpiderGL.Math.MIN_NUMBER. * * @returns {array} A 2-dimensional vector r, where r[i] = SpiderGL.Math.MIN_NUMBER. */ SpiderGL.Math.Vec2.minNumber = function () { return [SpiderGL.Math.MIN_NUMBER, SpiderGL.Math.MIN_NUMBER]; } /** * Creates a 3-dimensional vector from a 2-dimensional vector. * * @param {array} v The input vector. * @param {number} [z=0.0] The 3th component. * * @returns {array} A 4-dimensional vector r equal to v extended with z as 3rd component. */ SpiderGL.Math.Vec2.to3 = function (v, z) { return [v[0], v[1], (z != undefined) ? z : 0]; } /** * Creates a 4-dimensional vector from a 2-dimensional vector. * * @param {array} v The input vector. * @param {number} [z=0.0] The 3th component. * @param {number} [w=1.0] The 4th component. * * @returns {array} A 4-dimensional vector r equal to v extended with z as 3rd component and w as 4th component. */ SpiderGL.Math.Vec2.to4 = function (v, z, w) { return [v[0], v[1], v[2], (z != undefined) ? z : 0, (w != undefined) ? w : 1]; } /** * Component-wise negation of a 2-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 2-dimensionals vector r, where r[i] = -v[i]. */ SpiderGL.Math.Vec2.neg = function (v) { return [-v[0], -v[1]]; } /** * Component-wise addition of two 2-dimensional vectors. * * @param {array} u The first addition operand. * @param {array} v The second addition operand. * * @returns {array} A 2-dimensionals vector r, where r[i] = u[i] + v[i]. */ SpiderGL.Math.Vec2.add = function (u, v) { return [u[0]+v[0], u[1]+v[1]]; } /** * Component-wise addition of a 2-dimensional vector and a scalar. * * @param {array} v The vector addition operand. * @param {number} s The scalar addition operand. * * @returns {array} A 2-dimensionals vector r, where r[i] = v[i] + s. */ SpiderGL.Math.Vec2.adds = function (v, s) { return [v[0]+s, v[1]+s]; } /** * Component-wise subtraction of two 2-dimensional vectors. * * @param {array} u The first subtraction operand. * @param {array} v The second subtraction operand. * * @returns {array} A 2-dimensionals vector r, where r[i] = u[i] - v[i]. */ SpiderGL.Math.Vec2.sub = function (u, v) { return [u[0]-v[0], u[1]-v[1]]; } /** * Component-wise subtraction of a 2-dimensional vector and a scalar. * * @param {array} v The vector subtraction operand. * @param {number} s The scalar subtraction operand. * * @returns {array} A 2-dimensionals vector r, where r[i] = v[i] - s. */ SpiderGL.Math.Vec2.subs = function (v, s) { return [v[0]-s, v[1]-s]; } /** * Component-wise subtraction of a scalar and a 2-dimensional. * * @param {number} s The scalar subtraction operand. * @param {array} v The vector subtraction operand. * * @returns {array} A 2-dimensionals vector r, where r[i] = s - v[i]. */ SpiderGL.Math.Vec2.ssub = function (s, v) { return [s-v[0], s-v[1]]; } /** * Component-wise multiplication of two 2-dimensional vectors. * * @param {array} u The first multiplication operand. * @param {array} v The second multiplication operand. * * @returns {array} A 2-dimensionals vector r, where r[i] = u[i] * v[i]. */ SpiderGL.Math.Vec2.mul = function (u, v) { return [u[0]*v[0], u[1]*v[1]]; } /** * Component-wise multiplication of a 2-dimensional vector and a scalar. * * @param {array} v The vector multiplication operand. * @param {number} s The scalar multiplication operand. * * @returns {array} A 2-dimensionals vector r, where r[i] = v[i] * s. */ SpiderGL.Math.Vec2.muls = function (v, s) { return [v[0]*s, v[1]*s]; } /** * Component-wise division of two 2-dimensional vectors. * * @param {array} u The numerator vector. * @param {array} v The denominator vector. * * @returns {array} A 2-dimensionals vector r, where r[i] = u[i] / v[i]. */ SpiderGL.Math.Vec2.div = function (u, v) { return [u[0]/v[0], u[1]/v[1]]; } /** * Component-wise division of a 2-dimensional vector by a scalar. * * @param {array} v The numerator vector. * @param {number} s The scalar denominator. * * @returns {array} A 2-dimensionals vector r, where r[i] = v[i] / s. */ SpiderGL.Math.Vec2.divs = function (v, s) { return [v[0]/s, v[1]/s]; } /** * Component-wise division of a scalar by a 2-dimensional vector. * * @param {number} s The denominator scalar. * @param {array} v The numerator vector. * * @returns {array} A 2-dimensionals vector r, where r[i] = s / v[i]. */ SpiderGL.Math.Vec2.sdiv = function (s, v) { return [s/v[0], s/v[1]]; } /** * Component-wise reciprocal of a 2-dimensional vector. * * @param {array} v The input (denominator) vector. * * @returns {array} A 2-dimensionals vector r, where r[i] = 1.0 / v[i]. */ SpiderGL.Math.Vec2.rcp = function (v) { return [1.0/v[0], 1.0/v[1]]; } /** * Dot product of two 2-dimensional vectors. * * @param {array} u The first vector operand. * @param {array} v The second vector operand. * * @returns {number} The dot product of u and v. */ SpiderGL.Math.Vec2.dot = function (u, v) { return (u[0]*v[0] + u[1]*v[1]); } /** * Cross product of two 2-dimensional vectors. * * @param {array} u The first vector operand. * @param {array} v The second vector operand. * * @returns {array} A 2-dimensional vector equal to the cross product of u and v. */ SpiderGL.Math.Vec2.cross = function (u, v) { return (u[0]*v[1] - u[1]*v[0]); } /** * Perp operation. * Returns a 2-dimensional vector which is orthogonal to the input vector and lies in the right halfspace. * * @param {array} v The input vector. * * @returns {array} A 2-dimensional vector r, where r = [v[1], -v[0]]. */ SpiderGL.Math.Vec2.perp = function (v) { return [v[1], -v[0]]; } /** * Squared length of a 2-dimensional vector. * * @param {array} v The input vector. * * @returns {number} The squared length of v, same as the dot product of v with itself. */ SpiderGL.Math.Vec2.sqLength = function (v) { return SpiderGL.Math.Vec2.dot(v, v); } /** * Length of a 2-dimensional vector. * * @param {array} v The input vector. * * @returns {number} The length of v. */ SpiderGL.Math.Vec2.length = function (v) { return SpiderGL.Math.sqrt(SpiderGL.Math.Vec2.sqLength(v)); } /** * Creates a normalized 2-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 2-dimensional vector r representing the normalized v, where r[i] = v[i] / {@link SpiderGL.Math.Vec2.length}(v). */ SpiderGL.Math.Vec2.normalize = function (v) { var f = 1.0 / SpiderGL.Math.Vec2.length(v); return SpiderGL.Math.Vec2.muls(v, f); } /** * Component-wise absolute value of a 2-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 2-dimensional vector r, where r[i] = {@link SpiderGL.Math.abs}(v[i]). */ SpiderGL.Math.Vec2.abs = function (v) { return [SpiderGL.Math.abs(v[0]), SpiderGL.Math.abs(v[1])]; } /** * Component-wise arccosine of a 2-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 2-dimensional vector r, where r[i] = {@link SpiderGL.Math.acos}(v[i]), in radians. */ SpiderGL.Math.Vec2.acos = function (v) { return [SpiderGL.Math.acos(v[0]), SpiderGL.Math.acos(v[1])]; } /** * Component-wise arcsine of a 2-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 2-dimensional vector r, where r[i] = {@link SpiderGL.Math.asin}(v[i]), in radians. */ SpiderGL.Math.Vec2.asin = function (v) { return [SpiderGL.Math.asin(v[0]), SpiderGL.Math.asin(v[1])]; } /** * Component-wise arctangent of a 2-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 2-dimensional vector r, where r[i] = {@link SpiderGL.Math.atan}(v[i]), between -PI/2 and PI/2 radians. */ SpiderGL.Math.Vec2.atan = function (v) { return [SpiderGL.Math.atan(v[0]), SpiderGL.Math.atan(v[1])]; } /** * Component-wise arctangent of the quotient of two 2-dimensional vectors. * * @param {array} y The numerator vector. * @param {array} x The denominator vector. * * @returns {array} A 2-dimensional vector r, where r[i] = {@link SpiderGL.Math.atan2}(y[i], x[i]), between PI and -PI radians. */ SpiderGL.Math.Vec2.atan2 = function (y, x) { return [SpiderGL.Math.atan2(y[0], x[0]), SpiderGL.Math.atan2(y[1], x[1])]; } /** * Component-wise ceil of a 2-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 2-dimensional vector r, where r[i] = {@link SpiderGL.Math.ceil}(v[i]). */ SpiderGL.Math.Vec2.ceil = function (v) { return [SpiderGL.Math.ceil(v[0]), SpiderGL.Math.ceil(v[1])]; } /** * Component-wise clamp of a 2-dimensional vector with vector bounds. * * @param {array} v The input vector. * @param {array} min The lower 2-dimensional bound. * @param {array} max The upper 2-dimensional bound. * * @returns {array} A 2-dimensional vector r, where r[i] = {@link SpiderGL.Math.clamp}(v[i], min[i], max[i]). */ SpiderGL.Math.Vec2.clamp = function (v, min, max) { return [SpiderGL.Math.clamp(v[0], min[0], max[0]), SpiderGL.Math.clamp(v[1], min[1], max[1])]; } /** * Component-wise cosine of a 2-dimensional vector. * * @param {array} v The input vector, in radians. * * @returns {array} A 2-dimensional vector r, where r[i] = {@link SpiderGL.Math.cos}(v[i]). */ SpiderGL.Math.Vec2.cos = function (v) { return [SpiderGL.Math.cos(v[0]), SpiderGL.Math.cos(v[1])]; } /** * Component-wise conversion of a 2-dimensional vector from degrees to radians. * * @param {array} v The input vector, in radians. * * @returns {array} A 2-dimensional vector r, where r[i] = {@link SpiderGL.Math.degToRad}(v[i]). */ SpiderGL.Math.Vec2.degToRad = function (v) { return [SpiderGL.Math.degToRad(v[0]), SpiderGL.Math.degToRad(v[1])]; } /** * Component-wise exponential of a 2-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 2-dimensional vector r, where r[i] = {@link SpiderGL.Math.exp}(v[i]). */ SpiderGL.Math.Vec2.exp = function (v) { return [SpiderGL.Math.exp(v[0]), SpiderGL.Math.exp(v[1])]; } /** * Component-wise floor of a 2-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 2-dimensional vector r, where r[i] = {@link SpiderGL.Math.floor}(v[i]). */ SpiderGL.Math.Vec2.floor = function (v) { return [SpiderGL.Math.floor(v[0]), SpiderGL.Math.floor(v[1])]; } /** * Linear interpolation between two 2-dimensional vectors. * * @param {array} u The start interpolation bound. * @param {array} v The stop interpolation bound. * @param {number} t The interpolation factor, between 0 and 1. * * @returns {array} The interpolated vector r, where r[i] = (1-t)*u[i] + t*v[i]. */ SpiderGL.Math.Vec2.lerp = function (u, v, t) { return [ SpiderGL.Math.lerp(u[0], v[0], t), SpiderGL.Math.lerp(u[1], v[1], t) ]; } /** * Component-wise natural (base E) logarithm of a 2-dimensional vector. * Same as {@link SpiderGL.Math.Vec2.log}. * * @param {array} v The input vector. * * @returns {array} A 2-dimensional vector r, where r[i] = {@link SpiderGL.Math.ln}(v[i]). */ SpiderGL.Math.Vec2.ln = function (v) { return [SpiderGL.Math.ln(v[0]), SpiderGL.Math.ln(v[1])]; } /** * Component-wise natural (base E) logarithm of a 2-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 2-dimensional vector r, where r[i] = {@link SpiderGL.Math.log}(v[i]). */ SpiderGL.Math.Vec2.log = function (v) { return [SpiderGL.Math.log(v[0]), SpiderGL.Math.log(v[1])]; } /** * Component-wise base 2 logarithm of a 2-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 2-dimensional vector r, where r[i] = {@link SpiderGL.Math.log2}(v[i]). */ SpiderGL.Math.Vec2.log2 = function (v) { return [SpiderGL.Math.log2(v[0]), SpiderGL.Math.log2(v[1])]; } /** * Component-wise base 10 logarithm of a 2-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 2-dimensional vector r, where r[i] = {@link SpiderGL.Math.log10}(v[i]). */ SpiderGL.Math.Vec2.log10 = function (v) { return [SpiderGL.Math.log10(v[0]), SpiderGL.Math.log10(v[1])]; } /** * Component-wise maximum of two 2-dimensional vectors. * * @param {array} u The first vector. * @param {array} v The second vector. * * @returns {array} A 2-dimensional vector r, where r[i] = {@link SpiderGL.Math.max}(u[i], v[i]). */ SpiderGL.Math.Vec2.max = function (u, v) { return [SpiderGL.Math.max(u[0], v[0]), SpiderGL.Math.max(u[1], v[1])]; } /** * Component-wise minimum of two 2-dimensional vectors. * * @param {array} u The first vector. * @param {array} v The second vector. * * @returns {array} A 2-dimensional vector r, where r[i] = {@link SpiderGL.Math.min}(u[i], v[i]). */ SpiderGL.Math.Vec2.min = function (u, v) { return [SpiderGL.Math.min(u[0], v[0]), SpiderGL.Math.min(u[1], v[1])]; } /** * Component-wise power of two 2-dimensional vectors. * * @param {array} u The base vector. * @param {array} v The exponent vector. * * @returns {array} A 2-dimensional vector r, where r[i] = {@link SpiderGL.Math.pow}(u[i], v[i]). */ SpiderGL.Math.Vec2.pow = function (u, v) { return [SpiderGL.Math.pow(u[0], v[0]), SpiderGL.Math.pow(u[1], v[1])]; } /** * Component-wise conversion of a 2-dimensional vector from radians to degrees. * * @param {array} v The input vector, in degrees. * * @returns {array} A 2-dimensional vector r, where r[i] = {@link SpiderGL.Math.pow}(v[i]). */ SpiderGL.Math.Vec2.radToDeg = function (v) { return [SpiderGL.Math.radToDeg(v[0]), SpiderGL.Math.radToDeg(v[1])]; } /** * Creates a random 2-dimensional vector between 0 and 1. * * @returns {array} A 2-dimensional vector r, where r[i] = {@link SpiderGL.Math.random}(). */ SpiderGL.Math.Vec2.random = function () { return [SpiderGL.Math.random(), SpiderGL.Math.random()]; } /** * Creates a random 2-dimensional vector between 0 and 1. * Same as {@link SpiderGL.Math.Vec2.random}. * * @returns {array} A 2-dimensional vector r, where r[i] = {@link SpiderGL.Math.random01}(). */ SpiderGL.Math.Vec2.random01 = function () { return [SpiderGL.Math.random01(), SpiderGL.Math.random01()]; } /** * Creates a random 2-dimensional vector between -1 and 1. * * @returns {array} A 2-dimensional vector r, where r[i] = {@link SpiderGL.Math.random11}(). */ SpiderGL.Math.Vec2.random11 = function () { return [SpiderGL.Math.random11(), SpiderGL.Math.random11()]; } /** * Creates a random 2-dimensional vector inside a range. * * @param {array} min The range vector lower bound. * @param {array} max The range vector upper bound. * * @returns {array} A 2-dimensional vector r, where r[i] = {@link SpiderGL.Math.randomRange}(min[i], max[i]). */ SpiderGL.Math.Vec2.randomRange = function (min, max) { return [SpiderGL.Math.randomRange(min[0], max[0]), SpiderGL.Math.randomRange(min[1], max[1])]; } /** * Component-wise round of a 2-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 2-dimensional vector r, where r[i] = {@link SpiderGL.Math.round}(v[i]). */ SpiderGL.Math.Vec2.round = function (v) { return [SpiderGL.Math.round(v[0]), SpiderGL.Math.round(v[1])]; } /** * Component-wise sine of a 2-dimensional vector. * * @param {array} v The input vector, in radians. * * @returns {array} A 2-dimensional vector r, where r[i] = {@link SpiderGL.Math.sin}(v[i]). */ SpiderGL.Math.Vec2.sin = function (v) { return [SpiderGL.Math.sin(v[0]), SpiderGL.Math.sin(v[1])]; } /** * Component-wise square root of a 2-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 2-dimensional vector r, where r[i] = {@link SpiderGL.Math.sqrt}(v[i]). */ SpiderGL.Math.Vec2.sqrt = function (v) { return [SpiderGL.Math.sqrt(v[0]), SpiderGL.Math.sqrt(v[1])]; } /** * Component-wise tangent root of a 2-dimensional vector. * * @param {array} v The input vector, in radians. * * @returns {array} A 2-dimensional vector r, where r[i] = {@link SpiderGL.Math.tan}(v[i]). */ SpiderGL.Math.Vec2.tan = function (v) { return [SpiderGL.Math.tan(v[0]), SpiderGL.Math.tan(v[1])]; } /** * In-place component-wise copy of two 2-dimensional vectors. * * @param {array} u The destination vector. * @param {array} v The source vector. * * @returns {array} The destination vector u, where u[i] = v[i]. */ SpiderGL.Math.Vec2.copy$ = function (u, v) { u[0] = v[0]; u[1] = v[1]; return u; } /** * In-place component-wise negation of a 2-dimensional vector. * * @param {array} v The input vector. * * @returns {array} The input vector v, where v[i] = -v[i]. */ SpiderGL.Math.Vec2.neg$ = function (v) { v[0] = -v[0]; v[1] = -v[1]; return v; } /** * In-place component-wise addition of two 2-dimensional vectors. * * @param {array} u The first addition operand. * @param {array} v The second addition operand * * @returns {array} The input vector u, where u[i] = u[i] + v[i]. */ SpiderGL.Math.Vec2.add$ = function (u, v) { u[0] += v[0]; u[1] += v[1]; return u; } /** * In-place component-wise addition of a 2-dimensional vector and a scalar. * * @param {array} v The vector addition operand. * @param {number} s The scalar addition operand * * @returns {array} The input vector v, where v[i] = v[i] + s. */ SpiderGL.Math.Vec2.adds$ = function (v, s) { v[0] += s; v[1] += s; return v; } /** * In-place component-wise subtraction of two 2-dimensional vectors. * * @param {array} u The first addition operand. * @param {array} v The second addition operand * * @returns {array} The input vector u, where u[i] = u[i] - v[i]. */ SpiderGL.Math.Vec2.sub$ = function (u, v) { u[0] -= v[0]; u[1] -= v[1]; return u; } /** * In-place component-wise subtraction of a 2-dimensional vector and a scalar. * * @param {array} v The vector subtraction operand. * @param {number} s The scalar subtraction operand * * @returns {array} The input vector v, where v[i] = v[i] - s. */ SpiderGL.Math.Vec2.subs$ = function (v, s) { v[0] -= s; v[1] -= s; return v; } /** * In-place component-wise subtraction of a scalar and a 2-dimensional vector. * * @param {number} s The scalar subtraction operand * @param {array} v The vector subtraction operand. * * @returns {array} The input vector v, where v[i] = s - v[i]. */ SpiderGL.Math.Vec2.ssub$ = function (s, v) { v[0] = s - v[0]; v[1] = s - v[1]; return v; } /** * In-place component-wise multiplication of two 2-dimensional vectors. * * @param {array} u The first multiplication operand. * @param {array} v The second multiplication operand * * @returns {array} The input vector u, where u[i] = u[i] * v[i]. */ SpiderGL.Math.Vec2.mul$ = function (u, v) { u[0] *= v[0]; u[1] *= v[1]; return u; } /** * In-place component-wise multiplication of a 2-dimensional vector and a scalar. * * @param {array} v The first multiplication operand. * @param {number} s The second multiplication operand * * @returns {array} The input vector v, where v[i] = v[i] * s. */ SpiderGL.Math.Vec2.muls$ = function (v, s) { v[0] *= s; v[1] *= s; return v; } /** * In-place component-wise division of two 2-dimensional vectors. * * @param {array} u The numerator vector. * @param {array} v The denominator vector. * * @returns {array} The input vector u, where u[i] = u[i] / v[i]. */ SpiderGL.Math.Vec2.div$ = function (u, v) { u[0] /= v[0]; u[1] /= v[1]; return u; } /** * In-place component-wise division of a 2-dimensional vector by a scalar. * * @param {array} v The numerator vector. * @param {number} s The scalar denominator. * * @returns {array} The input vector v, where v[i] = v[i] / s. */ SpiderGL.Math.Vec2.divs$ = function (v, s) { v[0] /= s; v[1] /= s; return v; } /** * In-place component-wise division of a scalar by a 2-dimensional. * * @param {number} s The scalar numerator. * @param {array} v The denominator vector. * * @returns {array} The input vector v, where v[i] = s / v[i]. */ SpiderGL.Math.Vec2.sdiv$ = function (v, s) { v[0] = s / v[0]; v[1] = s / v[1]; return v; } /** * In-place perp operation. * Returns a 2-dimensional vector which is orthogonal to the input vector and lies in the right halfspace. * * @param {array} v The input vector. * * @returns {array} The input vector v, where v = [v[1], -v[0]]. */ SpiderGL.Math.Vec2.perp$ = function (v) { var v0 = v[0]; v[0] = v[1]; v[1] = -v0; return v; } /** * In-place 2-dimensional vector normalization. * * @param {array} v The input vector. * * @returns {array} The input vector v, where v[i] = v[i] / {@link SpiderGL.Math.Vec2.length}(v). */ SpiderGL.Math.Vec2.normalize$ = function (v) { var f = 1.0 / SpiderGL.Math.Vec2.length(v); return SpiderGL.Math.Vec2.muls$(v, f); } /*---------------------------------------------------------*/ // 3-dimensional vector /*---------------------------------------------------------*/ /** * The SpiderGL.Math.Vec3 namespace. * The provided functions operate on 3-dimensional vectors, represented as standard JavaScript arrays of length 3. * In general, vectors are considered as column vectors. * * @namespace The SpiderGL.Math.Vec3 namespace defines operations on 3-dimensional vectors. */ SpiderGL.Math.Vec3 = { }; /** * Duplicates the input 3-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 3-dimensional vector r, where r[i] = v[i] (same as v.slice(0, 3)). */ SpiderGL.Math.Vec3.dup = function (v) { return v.slice(0, 3); } /** * Creates a 3-dimensional vector initialized with a scalar. * * @param {number} s The input scalar. * * @returns {array} A 3-dimensional vector r, where r[i] = s. */ SpiderGL.Math.Vec3.scalar = function (s) { return [s, s, s]; } /** * Creates a 3-dimensional vector initialized with zero. * * @returns {array} A 3-dimensional vector r, where r[i] = 0. */ SpiderGL.Math.Vec3.zero = function () { return [0, 0, 0]; } /** * Creates a 3-dimensional vector initialized with one. * * @returns {array} A 3-dimensional vector r, where r[i] = 1.0. */ SpiderGL.Math.Vec3.one = function () { return [1, 1, 1]; } /** * Creates a 3-dimensional vector initialized with SpiderGL.Math.MAX_NUMBER. * * @returns {array} A 3-dimensional vector r, where r[i] = SpiderGL.Math.MAX_NUMBER. */ SpiderGL.Math.Vec3.maxNumber = function () { return [SpiderGL.Math.MAX_NUMBER, SpiderGL.Math.MAX_NUMBER, SpiderGL.Math.MAX_NUMBER]; } /** * Creates a 3-dimensional vector initialized with SpiderGL.Math.MIN_NUMBER. * * @returns {array} A 3-dimensional vector r, where r[i] = SpiderGL.Math.MIN_NUMBER. */ SpiderGL.Math.Vec3.minNumber = function () { return [SpiderGL.Math.MIN_NUMBER, SpiderGL.Math.MIN_NUMBER, SpiderGL.Math.MIN_NUMBER]; } /** * Creates a 2-dimensional vector from a 3-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 2-dimensional vector r equal to v with the 3rd component dropped. */ SpiderGL.Math.Vec3.to2 = function (v) { return [v[0], v[1]]; } /** * Creates a 4-dimensional vector from a 3-dimensional vector. * * @param {array} v The input vector. * @param {number} [w=1.0] The 4th component. * * @returns {array} A 4-dimensional vector r equal to v extended with w as 4th component. */ SpiderGL.Math.Vec3.to4 = function (v, w) { return [v[0], v[1], v[2], (w != undefined) ? w : 1]; } /** * Component-wise negation of a 3-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 3-dimensionals vector r, where r[i] = -v[i]. */ SpiderGL.Math.Vec3.neg = function (v) { return [-v[0], -v[1], -v[2]]; } /** * Component-wise addition of two 3-dimensional vectors. * * @param {array} u The first addition operand. * @param {array} v The second addition operand. * * @returns {array} A 3-dimensionals vector r, where r[i] = u[i] + v[i]. */ SpiderGL.Math.Vec3.add = function (u, v) { return [u[0]+v[0], u[1]+v[1], u[2]+v[2]]; } /** * Component-wise addition of a 3-dimensional vector and a scalar. * * @param {array} v The vector addition operand. * @param {number} s The scalar addition operand. * * @returns {array} A 3-dimensionals vector r, where r[i] = v[i] + s. */ SpiderGL.Math.Vec3.adds = function (v, s) { return [v[0]+s, v[1]+s, v[2]+s]; } /** * Component-wise subtraction of two 3-dimensional vectors. * * @param {array} u The first subtraction operand. * @param {array} v The second subtraction operand. * * @returns {array} A 3-dimensionals vector r, where r[i] = u[i] - v[i]. */ SpiderGL.Math.Vec3.sub = function (u, v) { return [u[0]-v[0], u[1]-v[1], u[2]-v[2]]; } /** * Component-wise subtraction of a 3-dimensional vector and a scalar. * * @param {array} v The vector subtraction operand. * @param {number} s The scalar subtraction operand. * * @returns {array} A 3-dimensionals vector r, where r[i] = v[i] - s. */ SpiderGL.Math.Vec3.subs = function (v, s) { return [v[0]-s, v[1]-s, v[2]-s]; } /** * Component-wise subtraction of a scalar and a 3-dimensional. * * @param {number} s The scalar subtraction operand. * @param {array} v The vector subtraction operand. * * @returns {array} A 3-dimensionals vector r, where r[i] = s - v[i]. */ SpiderGL.Math.Vec3.ssub = function (s, v) { return [s-v[0], s-v[1], s-v[2]]; } /** * Component-wise multiplication of two 3-dimensional vectors. * * @param {array} u The first multiplication operand. * @param {array} v The second multiplication operand. * * @returns {array} A 3-dimensionals vector r, where r[i] = u[i] * v[i]. */ SpiderGL.Math.Vec3.mul = function (u, v) { return [u[0]*v[0], u[1]*v[1], u[2]*v[2]]; } /** * Component-wise multiplication of a 3-dimensional vector and a scalar. * * @param {array} v The vector multiplication operand. * @param {number} s The scalar multiplication operand. * * @returns {array} A 3-dimensionals vector r, where r[i] = v[i] * s. */ SpiderGL.Math.Vec3.muls = function (v, s) { return [v[0]*s, v[1]*s, v[2]*s]; } /** * Component-wise division of two 3-dimensional vectors. * * @param {array} u The numerator vector. * @param {array} v The denominator vector. * * @returns {array} A 3-dimensionals vector r, where r[i] = u[i] / v[i]. */ SpiderGL.Math.Vec3.div = function (u, v) { return [u[0]/v[0], u[1]/v[1], u[2]/v[2]]; } /** * Component-wise division of a 3-dimensional vector by a scalar. * * @param {array} v The numerator vector. * @param {number} s The scalar denominator. * * @returns {array} A 3-dimensionals vector r, where r[i] = v[i] / s. */ SpiderGL.Math.Vec3.divs = function (v, s) { return [v[0]/s, v[1]/s, v[2]/s]; } /** * Component-wise division of a scalar by a 3-dimensional vector. * * @param {number} s The denominator scalar. * @param {array} v The numerator vector. * * @returns {array} A 3-dimensionals vector r, where r[i] = s / v[i]. */ SpiderGL.Math.Vec3.sdiv = function (s, v) { return [s/v[0], s/v[1], s/v[2]]; } /** * Component-wise reciprocal of a 3-dimensional vector. * * @param {array} v The input (denominator) vector. * * @returns {array} A 3-dimensionals vector r, where r[i] = 1.0 / v[i]. */ SpiderGL.Math.Vec3.rcp = function (v) { return [1.0/v[0], 1.0/v[1], 1.0/v[2]]; } /** * Dot product of two 3-dimensional vectors. * * @param {array} u The first vector operand. * @param {array} v The second vector operand. * * @returns {number} The dot product of u and v. */ SpiderGL.Math.Vec3.dot = function (u, v) { return (u[0]*v[0] + u[1]*v[1] + u[2]*v[2]); } /** * Cross product of two 3-dimensional vectors. * * @param {array} u The first vector operand. * @param {array} v The second vector operand. * * @returns {array} A 3-dimensional vector equal to the cross product of u and v. */ SpiderGL.Math.Vec3.cross = function (u, v) { return [u[1]*v[2] - u[2]*v[1], u[2]*v[0] - u[0]*v[2], u[0]*v[1] - u[1]*v[0]]; } /** * Squared length of a 3-dimensional vector. * * @param {array} v The input vector. * * @returns {number} The squared length of v, same as the dot product of v with itself. */ SpiderGL.Math.Vec3.sqLength = function (v) { return SpiderGL.Math.Vec3.dot(v, v); } /** * Length of a 3-dimensional vector. * * @param {array} v The input vector. * * @returns {number} The length of v. */ SpiderGL.Math.Vec3.length = function (v) { return SpiderGL.Math.sqrt(SpiderGL.Math.Vec3.sqLength(v)); } /** * Creates a normalized 3-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 3-dimensional vector r representing the normalized v, where r[i] = v[i] / {@link SpiderGL.Math.Vec3.length}(v). */ SpiderGL.Math.Vec3.normalize = function (v) { var f = 1.0 / SpiderGL.Math.Vec3.length(v); return SpiderGL.Math.Vec3.muls(v, f); } /** * Component-wise absolute value of a 3-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 3-dimensional vector r, where r[i] = {@link SpiderGL.Math.abs}(v[i]). */ SpiderGL.Math.Vec3.abs = function (v) { return [SpiderGL.Math.abs(v[0]), SpiderGL.Math.abs(v[1]), SpiderGL.Math.abs(v[2])]; } /** * Component-wise arccosine of a 3-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 3-dimensional vector r, where r[i] = {@link SpiderGL.Math.acos}(v[i]), in radians. */ SpiderGL.Math.Vec3.acos = function (v) { return [SpiderGL.Math.acos(v[0]), SpiderGL.Math.acos(v[1]), SpiderGL.Math.acos(v[2])]; } /** * Component-wise arcsine of a 3-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 3-dimensional vector r, where r[i] = {@link SpiderGL.Math.asin}(v[i]), in radians. */ SpiderGL.Math.Vec3.asin = function (v) { return [SpiderGL.Math.asin(v[0]), SpiderGL.Math.asin(v[1]), SpiderGL.Math.asin(v[2])]; } /** * Component-wise arctangent of a 3-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 3-dimensional vector r, where r[i] = {@link SpiderGL.Math.atan}(v[i]), between -PI/2 and PI/2 radians. */ SpiderGL.Math.Vec3.atan = function (v) { return [SpiderGL.Math.atan(v[0]), SpiderGL.Math.atan(v[1]), SpiderGL.Math.atan(v[2])]; } /** * Component-wise arctangent of the quotient of two 3-dimensional vectors. * * @param {array} y The numerator vector. * @param {array} x The denominator vector. * * @returns {array} A 3-dimensional vector r, where r[i] = {@link SpiderGL.Math.atan2}(y[i], x[i]), between PI and -PI radians. */ SpiderGL.Math.Vec3.atan2 = function (y, x) { return [SpiderGL.Math.atan2(y[0], x[0]), SpiderGL.Math.atan2(y[1], x[1]), SpiderGL.Math.atan2(y[2], x[2])]; } /** * Component-wise ceil of a 3-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 3-dimensional vector r, where r[i] = {@link SpiderGL.Math.ceil}(v[i]). */ SpiderGL.Math.Vec3.ceil = function (v) { return [SpiderGL.Math.ceil(v[0]), SpiderGL.Math.ceil(v[1]), SpiderGL.Math.ceil(v[2])]; } /** * Component-wise clamp of a 3-dimensional vector with vector bounds. * * @param {array} v The input vector. * @param {array} min The lower 3-dimensional bound. * @param {array} max The upper 3-dimensional bound. * * @returns {array} A 3-dimensional vector r, where r[i] = {@link SpiderGL.Math.clamp}(v[i], min[i], max[i]). */ SpiderGL.Math.Vec3.clamp = function (v, min, max) { return [SpiderGL.Math.clamp(v[0], min[0], max[0]), SpiderGL.Math.clamp(v[1], min[1], max[1]), SpiderGL.Math.clamp(v[2], min[2], max[2])]; } /** * Component-wise cosine of a 3-dimensional vector. * * @param {array} v The input vector, in radians. * * @returns {array} A 3-dimensional vector r, where r[i] = {@link SpiderGL.Math.cos}(v[i]). */ SpiderGL.Math.Vec3.cos = function (v) { return [SpiderGL.Math.cos(v[0]), SpiderGL.Math.cos(v[1]), SpiderGL.Math.cos(v[2])]; } /** * Component-wise conversion of a 3-dimensional vector from degrees to radians. * * @param {array} v The input vector, in radians. * * @returns {array} A 3-dimensional vector r, where r[i] = {@link SpiderGL.Math.degToRad}(v[i]). */ SpiderGL.Math.Vec3.degToRad = function (v) { return [SpiderGL.Math.degToRad(v[0]), SpiderGL.Math.degToRad(v[1]), SpiderGL.Math.degToRad(v[2])]; } /** * Component-wise exponential of a 3-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 3-dimensional vector r, where r[i] = {@link SpiderGL.Math.exp}(v[i]). */ SpiderGL.Math.Vec3.exp = function (v) { return [SpiderGL.Math.exp(v[0]), SpiderGL.Math.exp(v[1]), SpiderGL.Math.exp(v[2])]; } /** * Component-wise floor of a 3-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 3-dimensional vector r, where r[i] = {@link SpiderGL.Math.floor}(v[i]). */ SpiderGL.Math.Vec3.floor = function (v) { return [SpiderGL.Math.floor(v[0]), SpiderGL.Math.floor(v[1]), SpiderGL.Math.floor(v[2])]; } /** * Linear interpolation between two 3-dimensional vectors. * * @param {array} u The start interpolation bound. * @param {array} v The stop interpolation bound. * @param {number} t The interpolation factor, between 0 and 1. * * @returns {array} The interpolated vector r, where r[i] = (1-t)*u[i] + t*v[i]. */ SpiderGL.Math.Vec3.lerp = function (u, v, t) { return [ SpiderGL.Math.lerp(u[0], v[0], t), SpiderGL.Math.lerp(u[1], v[1], t), SpiderGL.Math.lerp(u[2], v[2], t) ]; } /** * Component-wise natural (base E) logarithm of a 3-dimensional vector. * Same as {@link SpiderGL.Math.Vec3.log}. * * @param {array} v The input vector. * * @returns {array} A 3-dimensional vector r, where r[i] = {@link SpiderGL.Math.ln}(v[i]). */ SpiderGL.Math.Vec3.ln = function (v) { return [SpiderGL.Math.ln(v[0]), SpiderGL.Math.ln(v[1]), SpiderGL.Math.ln(v[2])]; } /** * Component-wise natural (base E) logarithm of a 3-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 3-dimensional vector r, where r[i] = {@link SpiderGL.Math.log}(v[i]). */ SpiderGL.Math.Vec3.log = function (v) { return [SpiderGL.Math.log(v[0]), SpiderGL.Math.log(v[1]), SpiderGL.Math.log(v[2])]; } /** * Component-wise base 2 logarithm of a 3-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 3-dimensional vector r, where r[i] = {@link SpiderGL.Math.log2}(v[i]). */ SpiderGL.Math.Vec3.log2 = function (v) { return [SpiderGL.Math.log2(v[0]), SpiderGL.Math.log2(v[1]), SpiderGL.Math.log2(v[2])]; } /** * Component-wise base 10 logarithm of a 3-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 3-dimensional vector r, where r[i] = {@link SpiderGL.Math.log10}(v[i]). */ SpiderGL.Math.Vec3.log10 = function (v) { return [SpiderGL.Math.log10(v[0]), SpiderGL.Math.log10(v[1]), SpiderGL.Math.log10(v[2])]; } /** * Component-wise maximum of two 3-dimensional vectors. * * @param {array} u The first vector. * @param {array} v The second vector. * * @returns {array} A 3-dimensional vector r, where r[i] = {@link SpiderGL.Math.max}(u[i], v[i]). */ SpiderGL.Math.Vec3.max = function (u, v) { return [SpiderGL.Math.max(u[0], v[0]), SpiderGL.Math.max(u[1], v[1]), SpiderGL.Math.max(u[2], v[2])]; } /** * Component-wise minimum of two 3-dimensional vectors. * * @param {array} u The first vector. * @param {array} v The second vector. * * @returns {array} A 3-dimensional vector r, where r[i] = {@link SpiderGL.Math.min}(u[i], v[i]). */ SpiderGL.Math.Vec3.min = function (u, v) { return [SpiderGL.Math.min(u[0], v[0]), SpiderGL.Math.min(u[1], v[1]), SpiderGL.Math.min(u[2], v[2])]; } /** * Component-wise power of two 3-dimensional vectors. * * @param {array} u The base vector. * @param {array} v The exponent vector. * * @returns {array} A 3-dimensional vector r, where r[i] = {@link SpiderGL.Math.pow}(u[i], v[i]). */ SpiderGL.Math.Vec3.pow = function (u, v) { return [SpiderGL.Math.pow(u[0], v[0]), SpiderGL.Math.pow(u[1], v[1]), SpiderGL.Math.pow(u[2], v[2])]; } /** * Component-wise conversion of a 3-dimensional vector from radians to degrees. * * @param {array} v The input vector, in degrees. * * @returns {array} A 3-dimensional vector r, where r[i] = {@link SpiderGL.Math.pow}(v[i]). */ SpiderGL.Math.Vec3.radToDeg = function (v) { return [SpiderGL.Math.radToDeg(v[0]), SpiderGL.Math.radToDeg(v[1]), SpiderGL.Math.radToDeg(v[2])]; } /** * Creates a random 3-dimensional vector between 0 and 1. * * @returns {array} A 3-dimensional vector r, where r[i] = {@link SpiderGL.Math.random}(). */ SpiderGL.Math.Vec3.random = function () { return [SpiderGL.Math.random(), SpiderGL.Math.random(), SpiderGL.Math.random()]; } /** * Creates a random 3-dimensional vector between 0 and 1. * Same as {@link SpiderGL.Math.Vec3.random}. * * @returns {array} A 3-dimensional vector r, where r[i] = {@link SpiderGL.Math.random01}(). */ SpiderGL.Math.Vec3.random01 = function () { return [SpiderGL.Math.random01(), SpiderGL.Math.random01(), SpiderGL.Math.random01()]; } /** * Creates a random 3-dimensional vector between -1 and 1. * * @returns {array} A 3-dimensional vector r, where r[i] = {@link SpiderGL.Math.random11}(). */ SpiderGL.Math.Vec3.random11 = function () { return [SpiderGL.Math.random11(), SpiderGL.Math.random11(), SpiderGL.Math.random11()]; } /** * Creates a random 3-dimensional vector inside a range. * * @param {array} min The range vector lower bound. * @param {array} max The range vector upper bound. * * @returns {array} A 3-dimensional vector r, where r[i] = {@link SpiderGL.Math.randomRange}(min[i], max[i]). */ SpiderGL.Math.Vec3.randomRange = function (min, max) { return [SpiderGL.Math.randomRange(min[0], max[0]), SpiderGL.Math.randomRange(min[1], max[1]), SpiderGL.Math.randomRange(min[2], max[2])]; } /** * Component-wise round of a 3-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 3-dimensional vector r, where r[i] = {@link SpiderGL.Math.round}(v[i]). */ SpiderGL.Math.Vec3.round = function (v) { return [SpiderGL.Math.round(v[0]), SpiderGL.Math.round(v[1]), SpiderGL.Math.round(v[2])]; } /** * Component-wise sine of a 3-dimensional vector. * * @param {array} v The input vector, in radians. * * @returns {array} A 3-dimensional vector r, where r[i] = {@link SpiderGL.Math.sin}(v[i]). */ SpiderGL.Math.Vec3.sin = function (v) { return [SpiderGL.Math.sin(v[0]), SpiderGL.Math.sin(v[1]), SpiderGL.Math.sin(v[2])]; } /** * Component-wise square root of a 3-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 3-dimensional vector r, where r[i] = {@link SpiderGL.Math.sqrt}(v[i]). */ SpiderGL.Math.Vec3.sqrt = function (v) { return [SpiderGL.Math.sqrt(v[0]), SpiderGL.Math.sqrt(v[1]), SpiderGL.Math.sqrt(v[2])]; } /** * Component-wise tangent root of a 3-dimensional vector. * * @param {array} v The input vector, in radians. * * @returns {array} A 3-dimensional vector r, where r[i] = {@link SpiderGL.Math.tan}(v[i]). */ SpiderGL.Math.Vec3.tan = function (v) { return [SpiderGL.Math.tan(v[0]), SpiderGL.Math.tan(v[1]), SpiderGL.Math.tan(v[2])]; } /** * In-place component-wise copy of two 3-dimensional vectors. * * @param {array} u The destination vector. * @param {array} v The source vector. * * @returns {array} The destination vector u, where u[i] = v[i]. */ SpiderGL.Math.Vec3.copy$ = function (u, v) { u[0] = v[0]; u[1] = v[1]; u[2] = v[2]; return u; } /** * In-place component-wise negation of a 3-dimensional vector. * * @param {array} v The input vector. * * @returns {array} The input vector v, where v[i] = -v[i]. */ SpiderGL.Math.Vec3.neg$ = function (v) { v[0] = -v[0]; v[1] = -v[1]; v[2] = -v[2]; return v; } /** * In-place component-wise addition of two 3-dimensional vectors. * * @param {array} u The first addition operand. * @param {array} v The second addition operand * * @returns {array} The input vector u, where u[i] = u[i] + v[i]. */ SpiderGL.Math.Vec3.add$ = function (u, v) { u[0] += v[0]; u[1] += v[1]; u[2] += v[2]; return u; } /** * In-place component-wise addition of a 3-dimensional vector and a scalar. * * @param {array} v The vector addition operand. * @param {number} s The scalar addition operand * * @returns {array} The input vector v, where v[i] = v[i] + s. */ SpiderGL.Math.Vec3.adds$ = function (v, s) { v[0] += s; v[1] += s; v[2] += s; return v; } /** * In-place component-wise subtraction of two 3-dimensional vectors. * * @param {array} u The first addition operand. * @param {array} v The second addition operand * * @returns {array} The input vector u, where u[i] = u[i] - v[i]. */ SpiderGL.Math.Vec3.sub$ = function (u, v) { u[0] -= v[0]; u[1] -= v[1]; u[2] -= v[2]; return u; } /** * In-place component-wise subtraction of a 3-dimensional vector and a scalar. * * @param {array} v The vector subtraction operand. * @param {number} s The scalar subtraction operand * * @returns {array} The input vector v, where v[i] = v[i] - s. */ SpiderGL.Math.Vec3.subs$ = function (v, s) { v[0] -= s; v[1] -= s; v[2] -= s; return v; } /** * In-place component-wise subtraction of a scalar and a 3-dimensional vector. * * @param {number} s The scalar subtraction operand * @param {array} v The vector subtraction operand. * * @returns {array} The input vector v, where v[i] = s - v[i]. */ SpiderGL.Math.Vec3.ssub$ = function (s, v) { v[0] = s - v[0]; v[1] = s - v[1]; v[2] = s - v[2]; return v; } /** * In-place component-wise multiplication of two 3-dimensional vectors. * * @param {array} u The first multiplication operand. * @param {array} v The second multiplication operand * * @returns {array} The input vector u, where u[i] = u[i] * v[i]. */ SpiderGL.Math.Vec3.mul$ = function (u, v) { u[0] *= v[0]; u[1] *= v[1]; u[2] *= v[2]; return u; } /** * In-place component-wise multiplication of a 3-dimensional vector and a scalar. * * @param {array} v The first multiplication operand. * @param {number} s The second multiplication operand * * @returns {array} The input vector v, where v[i] = v[i] * s. */ SpiderGL.Math.Vec3.muls$ = function (v, s) { v[0] *= s; v[1] *= s; v[2] *= s; return v; } /** * In-place component-wise division of two 3-dimensional vectors. * * @param {array} u The numerator vector. * @param {array} v The denominator vector. * * @returns {array} The input vector u, where u[i] = u[i] / v[i]. */ SpiderGL.Math.Vec3.div$ = function (u, v) { u[0] /= v[0]; u[1] /= v[1]; u[2] /= v[2]; return u; } /** * In-place component-wise division of a 3-dimensional vector by a scalar. * * @param {array} v The numerator vector. * @param {number} s The scalar denominator. * * @returns {array} The input vector v, where v[i] = v[i] / s. */ SpiderGL.Math.Vec3.divs$ = function (v, s) { v[0] /= s; v[1] /= s; v[2] /= s; return v; } /** * In-place component-wise division of a scalar by a 3-dimensional. * * @param {number} s The scalar numerator. * @param {array} v The denominator vector. * * @returns {array} The input vector v, where v[i] = s / v[i]. */ SpiderGL.Math.Vec3.sdiv$ = function (v, s) { v[0] = s / v[0]; v[1] = s / v[1]; v[2] = s / v[2]; return v; } /** * In-place 3-dimensional vector normalization. * * @param {array} v The input vector. * * @returns {array} The input vector v, where v[i] = v[i] / {@link SpiderGL.Math.Vec3.length}(v) */ SpiderGL.Math.Vec3.normalize$ = function (v) { var f = 1.0 / SpiderGL.Math.Vec3.length(v); return SpiderGL.Math.Vec3.muls$(v, f); } /*---------------------------------------------------------*/ // 4-dimensional vector /*---------------------------------------------------------*/ /** * The SpiderGL.Math.Vec4 namespace. * The provided functions operate on 4-dimensional vectors, represented as standard JavaScript arrays of length 4. * In general, vectors are considered as column vectors. * * @namespace The SpiderGL.Math.Vec4 namespace defines operations on 4-dimensional vectors. */ SpiderGL.Math.Vec4 = { }; /** * Duplicates the input 4-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 4-dimensional vector r, where r[i] = v[i] (same as v.slice(0, 4)). */ SpiderGL.Math.Vec4.dup = function (v) { return v.slice(0, 4); } /** * Creates a 4-dimensional vector initialized with a scalar. * * @param {number} s The input scalar. * * @returns {array} A 4-dimensional vector r, where r[i] = s. */ SpiderGL.Math.Vec4.scalar = function (s) { return [s, s, s, s]; } /** * Creates a 4-dimensional vector initialized with zero. * * @returns {array} A 4-dimensional vector r, where r[i] = 0. */ SpiderGL.Math.Vec4.zero = function () { return [0, 0, 0, 0]; } /** * Creates a 4-dimensional vector initialized with one. * * @returns {array} A 4-dimensional vector r, where r[i] = 1.0. */ SpiderGL.Math.Vec4.one = function () { return [1, 1, 1, 1]; } /** * Creates a 4-dimensional vector initialized with SpiderGL.Math.MAX_NUMBER. * * @returns {array} A 4-dimensional vector r, where r[i] = SpiderGL.Math.MAX_NUMBER. */ SpiderGL.Math.Vec4.maxNumber = function () { return [SpiderGL.Math.MAX_NUMBER, SpiderGL.Math.MAX_NUMBER, SpiderGL.Math.MAX_NUMBER, SpiderGL.Math.MAX_NUMBER]; } /** * Creates a 4-dimensional vector initialized with SpiderGL.Math.MIN_NUMBER. * * @returns {array} A 4-dimensional vector r, where r[i] = SpiderGL.Math.MIN_NUMBER. */ SpiderGL.Math.Vec4.minNumber = function () { return [SpiderGL.Math.MIN_NUMBER, SpiderGL.Math.MIN_NUMBER, SpiderGL.Math.MIN_NUMBER, SpiderGL.Math.MIN_NUMBER]; } /** * Creates a 2-dimensional vector from a 4-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 2-dimensional vector r equal to v with the 3rd and 4th components dropped. */ SpiderGL.Math.Vec4.to2 = function (v) { return [v[0], v[1]]; } /** * Creates a 3-dimensional vector from a 4-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 3-dimensional vector r equal to v with the 4th component dropped. */ SpiderGL.Math.Vec4.to3 = function (v) { return [v[0], v[1], v[2]]; } /** * Component-wise negation of a 4-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 4-dimensionals vector r, where r[i] = -v[i]. */ SpiderGL.Math.Vec4.neg = function (v) { return [-v[0], -v[1], -v[2], -v[3]]; } /** * Component-wise addition of two 4-dimensional vectors. * * @param {array} u The first addition operand. * @param {array} v The second addition operand. * * @returns {array} A 4-dimensionals vector r, where r[i] = u[i] + v[i]. */ SpiderGL.Math.Vec4.add = function (u, v) { return [u[0]+v[0], u[1]+v[1], u[2]+v[2], u[3]+v[3]]; } /** * Component-wise addition of a 4-dimensional vector and a scalar. * * @param {array} v The vector addition operand. * @param {number} s The scalar addition operand. * * @returns {array} A 4-dimensionals vector r, where r[i] = v[i] + s. */ SpiderGL.Math.Vec4.adds = function (v, s) { return [v[0]+s, v[1]+s, v[2]+s, v[3]+s]; } /** * Component-wise subtraction of two 4-dimensional vectors. * * @param {array} u The first subtraction operand. * @param {array} v The second subtraction operand. * * @returns {array} A 4-dimensionals vector r, where r[i] = u[i] - v[i]. */ SpiderGL.Math.Vec4.sub = function (u, v) { return [u[0]-v[0], u[1]-v[1], u[2]-v[2], u[3]-v[3]]; } /** * Component-wise subtraction of a 4-dimensional vector and a scalar. * * @param {array} v The vector subtraction operand. * @param {number} s The scalar subtraction operand. * * @returns {array} A 4-dimensionals vector r, where r[i] = v[i] - s. */ SpiderGL.Math.Vec4.subs = function (v, s) { return [v[0]-s, v[1]-s, v[2]-s, v[3]-s]; } /** * Component-wise subtraction of a scalar and a 4-dimensional. * * @param {number} s The scalar subtraction operand. * @param {array} v The vector subtraction operand. * * @returns {array} A 4-dimensionals vector r, where r[i] = s - v[i]. */ SpiderGL.Math.Vec4.ssub = function (s, v) { return [s-v[0], s-v[1], s-v[2], s-v[3]]; } /** * Component-wise multiplication of two 4-dimensional vectors. * * @param {array} u The first multiplication operand. * @param {array} v The second multiplication operand. * * @returns {array} A 4-dimensionals vector r, where r[i] = u[i] * v[i]. */ SpiderGL.Math.Vec4.mul = function (u, v) { return [u[0]*v[0], u[1]*v[1], u[2]*v[2], u[3]*v[3]]; } /** * Component-wise multiplication of a 4-dimensional vector and a scalar. * * @param {array} v The vector multiplication operand. * @param {number} s The scalar multiplication operand. * * @returns {array} A 4-dimensionals vector r, where r[i] = v[i] * s. */ SpiderGL.Math.Vec4.muls = function (v, s) { return [v[0]*s, v[1]*s, v[2]*s, v[3]*s]; } /** * Component-wise division of two 4-dimensional vectors. * * @param {array} u The numerator vector. * @param {array} v The denominator vector. * * @returns {array} A 4-dimensionals vector r, where r[i] = u[i] / v[i]. */ SpiderGL.Math.Vec4.div = function (u, v) { return [u[0]/v[0], u[1]/v[1], u[2]/v[2], u[3]/v[3]]; } /** * Component-wise division of a 4-dimensional vector by a scalar. * * @param {array} v The numerator vector. * @param {number} s The scalar denominator. * * @returns {array} A 4-dimensionals vector r, where r[i] = v[i] / s. */ SpiderGL.Math.Vec4.divs = function (v, s) { return [v[0]/s, v[1]/s, v[2]/s, v[3]/s]; } /** * Component-wise division of a scalar by a 4-dimensional vector. * * @param {number} s The denominator scalar. * @param {array} v The numerator vector. * * @returns {array} A 4-dimensionals vector r, where r[i] = s / v[i]. */ SpiderGL.Math.Vec4.sdiv = function (s, v) { return [s/v[0], s/v[1], s/v[2], s/v[3]]; } /** * Component-wise reciprocal of a 4-dimensional vector. * * @param {array} v The input (denominator) vector. * * @returns {array} A 4-dimensionals vector r, where r[i] = 1.0 / v[i]. */ SpiderGL.Math.Vec4.rcp = function (v) { return [1.0/v[0], 1.0/v[1], 1.0/v[2], 1.0/v[3]]; } /** * Dot product of two 4-dimensional vectors. * * @param {array} u The first vector operand. * @param {array} v The second vector operand. * * @returns {number} The dot product of u and v. */ SpiderGL.Math.Vec4.dot = function (u, v) { return (u[0]*v[0] + u[1]*v[1] + u[2]*v[2] + u[3]*v[3]); } /** * Cross product of three 4-dimensional vectors. * * @param {array} u The first vector operand. * @param {array} v The second vector operand. * @param {array} w The third vector operand. * * @returns {array} A 4-dimensional vector equal to the cross product of u, v and w. */ SpiderGL.Math.Vec4.cross = function (u, v, w) { var a = v[0]*w[1] - v[1]*w[0]; var b = v[0]*w[2] - v[2]*w[0]; var c = v[0]*w[3] - v[3]*w[0]; var d = v[1]*w[2] - v[2]*w[1]; var e = v[1]*w[3] - v[3]*w[1]; var f = v[2]*w[3] - v[3]*w[2]; return [ u[1]*f - u[2]*e + u[3]*d, u[0]*f + u[2]*c - u[3]*b, u[0]*e - u[1]*c + u[3]*a, u[0]*d + u[1]*b - u[2]*a ]; } /** * Squared length of a 4-dimensional vector. * * @param {array} v The input vector. * * @returns {number} The squared length of v, same as the dot product of v with itself. */ SpiderGL.Math.Vec4.sqLength = function (v) { return SpiderGL.Math.Vec4.dot(v, v); } /** * Length of a 4-dimensional vector. * * @param {array} v The input vector. * * @returns {number} The length of v. */ SpiderGL.Math.Vec4.length = function (v) { return SpiderGL.Math.sqrt(SpiderGL.Math.Vec4.sqLength(v)); } /** * Creates a normalized 4-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 4-dimensional vector r representing the normalized v, where r[i] = v[i] / {@link SpiderGL.Math.Vec4.length}(v). */ SpiderGL.Math.Vec4.normalize = function (v) { var f = 1.0 / SpiderGL.Math.Vec4.length(v); return SpiderGL.Math.Vec4.muls(v, f); } /** * Projects a homogeneous 4-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 4-dimensional vector r, where r[i] = v[i] / v[3]. */ SpiderGL.Math.Vec4.project = function (v) { var f = 1.0 / v[3]; return [v[0]*f, v[1]*f, v[2]*f, 1.0]; } /** * Component-wise absolute value of a 4-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 4-dimensional vector r, where r[i] = {@link SpiderGL.Math.abs}(v[i]). */ SpiderGL.Math.Vec4.abs = function (v) { return [SpiderGL.Math.abs(v[0]), SpiderGL.Math.abs(v[1]), SpiderGL.Math.abs(v[2]), SpiderGL.Math.abs(v[3])]; } /** * Component-wise arccosine of a 4-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 4-dimensional vector r, where r[i] = {@link SpiderGL.Math.acos}(v[i]), in radians. */ SpiderGL.Math.Vec4.acos = function (v) { return [SpiderGL.Math.acos(v[0]), SpiderGL.Math.acos(v[1]), SpiderGL.Math.acos(v[2]), SpiderGL.Math.acos(v[3])]; } /** * Component-wise arcsine of a 4-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 4-dimensional vector r, where r[i] = {@link SpiderGL.Math.asin}(v[i]), in radians. */ SpiderGL.Math.Vec4.asin = function (v) { return [SpiderGL.Math.asin(v[0]), SpiderGL.Math.asin(v[1]), SpiderGL.Math.asin(v[2]), SpiderGL.Math.asin(v[3])]; } /** * Component-wise arctangent of a 4-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 4-dimensional vector r, where r[i] = {@link SpiderGL.Math.atan}(v[i]), between -PI/2 and PI/2 radians. */ SpiderGL.Math.Vec4.atan = function (v) { return [SpiderGL.Math.atan(v[0]), SpiderGL.Math.atan(v[1]), SpiderGL.Math.atan(v[2]), SpiderGL.Math.atan(v[3])]; } /** * Component-wise arctangent of the quotient of two 4-dimensional vectors. * * @param {array} y The numerator vector. * @param {array} x The denominator vector. * * @returns {array} A 4-dimensional vector r, where r[i] = {@link SpiderGL.Math.atan2}(y[i], x[i]), between PI and -PI radians. */ SpiderGL.Math.Vec4.atan2 = function (y, x) { return [SpiderGL.Math.atan2(y[0], x[0]), SpiderGL.Math.atan2(y[1], x[1]), SpiderGL.Math.atan2(y[2], x[2]), SpiderGL.Math.atan2(y[3], x[3])]; } /** * Component-wise ceil of a 4-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 4-dimensional vector r, where r[i] = {@link SpiderGL.Math.ceil}(v[i]). */ SpiderGL.Math.Vec4.ceil = function (v) { return [SpiderGL.Math.ceil(v[0]), SpiderGL.Math.ceil(v[1]), SpiderGL.Math.ceil(v[2]), SpiderGL.Math.ceil(v[3])]; } /** * Component-wise clamp of a 4-dimensional vector with vector bounds. * * @param {array} v The input vector. * @param {array} min The lower 4-dimensional bound. * @param {array} max The upper 4-dimensional bound. * * @returns {array} A 4-dimensional vector r, where r[i] = {@link SpiderGL.Math.clamp}(v[i], min[i], max[i]). */ SpiderGL.Math.Vec4.clamp = function (v, min, max) { return [SpiderGL.Math.clamp(v[0], min[0], max[0]), SpiderGL.Math.clamp(v[1], min[1], max[1]), SpiderGL.Math.clamp(v[2], min[2], max[2]), SpiderGL.Math.clamp(v[3], min[3], max[3])]; } /** * Component-wise cosine of a 4-dimensional vector. * * @param {array} v The input vector, in radians. * * @returns {array} A 4-dimensional vector r, where r[i] = {@link SpiderGL.Math.cos}(v[i]). */ SpiderGL.Math.Vec4.cos = function (v) { return [SpiderGL.Math.cos(v[0]), SpiderGL.Math.cos(v[1]), SpiderGL.Math.cos(v[2]), SpiderGL.Math.cos(v[3])]; } /** * Component-wise conversion of a 4-dimensional vector from degrees to radians. * * @param {array} v The input vector, in radians. * * @returns {array} A 4-dimensional vector r, where r[i] = {@link SpiderGL.Math.degToRad}(v[i]). */ SpiderGL.Math.Vec4.degToRad = function (v) { return [SpiderGL.Math.degToRad(v[0]), SpiderGL.Math.degToRad(v[1]), SpiderGL.Math.degToRad(v[2]), SpiderGL.Math.degToRad(v[3])]; } /** * Component-wise exponential of a 4-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 4-dimensional vector r, where r[i] = {@link SpiderGL.Math.exp}(v[i]). */ SpiderGL.Math.Vec4.exp = function (v) { return [SpiderGL.Math.exp(v[0]), SpiderGL.Math.exp(v[1]), SpiderGL.Math.exp(v[2]), SpiderGL.Math.exp(v[3])]; } /** * Component-wise floor of a 4-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 4-dimensional vector r, where r[i] = {@link SpiderGL.Math.floor}(v[i]). */ SpiderGL.Math.Vec4.floor = function (v) { return [SpiderGL.Math.floor(v[0]), SpiderGL.Math.floor(v[1]), SpiderGL.Math.floor(v[2]), SpiderGL.Math.floor(v[3])]; } /** * Linear interpolation between two 4-dimensional vectors. * * @param {array} u The start interpolation bound. * @param {array} v The stop interpolation bound. * @param {number} t The interpolation factor, between 0 and 1. * * @returns {array} The interpolated vector r, where r[i] = (1-t)*u[i] + t*v[i]. */ SpiderGL.Math.Vec4.lerp = function (u, v, t) { return [ SpiderGL.Math.lerp(u[0], v[0], t), SpiderGL.Math.lerp(u[1], v[1], t), SpiderGL.Math.lerp(u[2], v[2], t), SpiderGL.Math.lerp(u[3], v[3], t) ]; } /** * Component-wise natural (base E) logarithm of a 4-dimensional vector. * Same as {@link SpiderGL.Math.Vec4.log}. * * @param {array} v The input vector. * * @returns {array} A 4-dimensional vector r, where r[i] = {@link SpiderGL.Math.ln}(v[i]). */ SpiderGL.Math.Vec4.ln = function (v) { return [SpiderGL.Math.ln(v[0]), SpiderGL.Math.ln(v[1]), SpiderGL.Math.ln(v[2]), SpiderGL.Math.ln(v[3])]; } /** * Component-wise natural (base E) logarithm of a 4-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 4-dimensional vector r, where r[i] = {@link SpiderGL.Math.log}(v[i]). */ SpiderGL.Math.Vec4.log = function (v) { return [SpiderGL.Math.log(v[0]), SpiderGL.Math.log(v[1]), SpiderGL.Math.log(v[2]), SpiderGL.Math.log(v[3])]; } /** * Component-wise base 2 logarithm of a 4-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 4-dimensional vector r, where r[i] = {@link SpiderGL.Math.log2}(v[i]). */ SpiderGL.Math.Vec4.log2 = function (v) { return [SpiderGL.Math.log2(v[0]), SpiderGL.Math.log2(v[1]), SpiderGL.Math.log2(v[2]), SpiderGL.Math.log2(v[3])]; } /** * Component-wise base 10 logarithm of a 4-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 4-dimensional vector r, where r[i] = {@link SpiderGL.Math.log10}(v[i]). */ SpiderGL.Math.Vec4.log10 = function (v) { return [SpiderGL.Math.log10(v[0]), SpiderGL.Math.log10(v[1]), SpiderGL.Math.log10(v[2]), SpiderGL.Math.log10(v[3])]; } /** * Component-wise maximum of two 4-dimensional vectors. * * @param {array} u The first vector. * @param {array} v The second vector. * * @returns {array} A 4-dimensional vector r, where r[i] = {@link SpiderGL.Math.max}(u[i], v[i]). */ SpiderGL.Math.Vec4.max = function (u, v) { return [SpiderGL.Math.max(u[0], v[0]), SpiderGL.Math.max(u[1], v[1]), SpiderGL.Math.max(u[2], v[2]), SpiderGL.Math.max(u[3], v[3])]; } /** * Component-wise minimum of two 4-dimensional vectors. * * @param {array} u The first vector. * @param {array} v The second vector. * * @returns {array} A 4-dimensional vector r, where r[i] = {@link SpiderGL.Math.min}(u[i], v[i]). */ SpiderGL.Math.Vec4.min = function (u, v) { return [SpiderGL.Math.min(u[0], v[0]), SpiderGL.Math.min(u[1], v[1]), SpiderGL.Math.min(u[2], v[2]), SpiderGL.Math.min(u[3], v[3])]; } /** * Component-wise power of two 4-dimensional vectors. * * @param {array} u The base vector. * @param {array} v The exponent vector. * * @returns {array} A 4-dimensional vector r, where r[i] = {@link SpiderGL.Math.pow}(u[i], v[i]). */ SpiderGL.Math.Vec4.pow = function (u, v) { return [SpiderGL.Math.pow(u[0], v[0]), SpiderGL.Math.pow(u[1], v[1]), SpiderGL.Math.pow(u[2], v[2]), SpiderGL.Math.pow(u[3], v[3])]; } /** * Component-wise conversion of a 4-dimensional vector from radians to degrees. * * @param {array} v The input vector, in degrees. * * @returns {array} A 4-dimensional vector r, where r[i] = {@link SpiderGL.Math.pow}(v[i]). */ SpiderGL.Math.Vec4.radToDeg = function (v) { return [SpiderGL.Math.radToDeg(v[0]), SpiderGL.Math.radToDeg(v[1]), SpiderGL.Math.radToDeg(v[2]), SpiderGL.Math.radToDeg(v[3])]; } /** * Creates a random 4-dimensional vector between 0 and 1. * * @returns {array} A 4-dimensional vector r, where r[i] = {@link SpiderGL.Math.random}(). */ SpiderGL.Math.Vec4.random = function () { return [SpiderGL.Math.random(), SpiderGL.Math.random(), SpiderGL.Math.random(), SpiderGL.Math.random()]; } /** * Creates a random 4-dimensional vector between 0 and 1. * Same as {@link SpiderGL.Math.Vec4.random}. * * @returns {array} A 4-dimensional vector r, where r[i] = {@link SpiderGL.Math.random01}(). */ SpiderGL.Math.Vec4.random01 = function () { return [SpiderGL.Math.random01(), SpiderGL.Math.random01(), SpiderGL.Math.random01(), SpiderGL.Math.random01()]; } /** * Creates a random 4-dimensional vector between -1 and 1. * * @returns {array} A 4-dimensional vector r, where r[i] = {@link SpiderGL.Math.random11}(). */ SpiderGL.Math.Vec4.random11 = function () { return [SpiderGL.Math.random11(), SpiderGL.Math.random11(), SpiderGL.Math.random11(), SpiderGL.Math.random11()]; } /** * Creates a random 4-dimensional vector inside a range. * * @param {array} min The range vector lower bound. * @param {array} max The range vector upper bound. * * @returns {array} A 4-dimensional vector r, where r[i] = {@link SpiderGL.Math.randomRange}(min[i], max[i]). */ SpiderGL.Math.Vec4.randomRange = function (min, max) { return [SpiderGL.Math.randomRange(min[0], max[0]), SpiderGL.Math.randomRange(min[1], max[1]), SpiderGL.Math.randomRange(min[2], max[2]), SpiderGL.Math.randomRange(min[3], max[3])]; } /** * Component-wise round of a 4-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 4-dimensional vector r, where r[i] = {@link SpiderGL.Math.round}(v[i]). */ SpiderGL.Math.Vec4.round = function (v) { return [SpiderGL.Math.round(v[0]), SpiderGL.Math.round(v[1]), SpiderGL.Math.round(v[2]), SpiderGL.Math.round(v[3])]; } /** * Component-wise sine of a 4-dimensional vector. * * @param {array} v The input vector, in radians. * * @returns {array} A 4-dimensional vector r, where r[i] = {@link SpiderGL.Math.sin}(v[i]). */ SpiderGL.Math.Vec4.sin = function (v) { return [SpiderGL.Math.sin(v[0]), SpiderGL.Math.sin(v[1]), SpiderGL.Math.sin(v[2]), SpiderGL.Math.sin(v[3])]; } /** * Component-wise square root of a 4-dimensional vector. * * @param {array} v The input vector. * * @returns {array} A 4-dimensional vector r, where r[i] = {@link SpiderGL.Math.sqrt}(v[i]). */ SpiderGL.Math.Vec4.sqrt = function (v) { return [SpiderGL.Math.sqrt(v[0]), SpiderGL.Math.sqrt(v[1]), SpiderGL.Math.sqrt(v[2]), SpiderGL.Math.sqrt(v[3])]; } /** * Component-wise tangent root of a 4-dimensional vector. * * @param {array} v The input vector, in radians. * * @returns {array} A 4-dimensional vector r, where r[i] = {@link SpiderGL.Math.tan}(v[i]). */ SpiderGL.Math.Vec4.tan = function (v) { return [SpiderGL.Math.tan(v[0]), SpiderGL.Math.tan(v[1]), SpiderGL.Math.tan(v[2]), SpiderGL.Math.tan(v[3])]; } /** * In-place component-wise copy of two 4-dimensional vectors. * * @param {array} u The destination vector. * @param {array} v The source vector. * * @returns {array} The destination vector u, where u[i] = v[i]. */ SpiderGL.Math.Vec4.copy$ = function (u, v) { u[0] = v[0]; u[1] = v[1]; u[2] = v[2]; u[3] = v[3]; return u; } /** * In-place component-wise negation of a 4-dimensional vector. * * @param {array} v The input vector. * * @returns {array} The input vector v, where v[i] = -v[i]. */ SpiderGL.Math.Vec4.neg$ = function (v) { v[0] = -v[0]; v[1] = -v[1]; v[2] = -v[2]; v[3] = -v[3]; return v; } /** * In-place component-wise addition of two 4-dimensional vectors. * * @param {array} u The first addition operand. * @param {array} v The second addition operand * * @returns {array} The input vector u, where u[i] = u[i] + v[i]. */ SpiderGL.Math.Vec4.add$ = function (u, v) { u[0] += v[0]; u[1] += v[1]; u[2] += v[2]; u[3] += v[3]; return u; } /** * In-place component-wise addition of a 4-dimensional vector and a scalar. * * @param {array} v The vector addition operand. * @param {number} s The scalar addition operand * * @returns {array} The input vector v, where v[i] = v[i] + s. */ SpiderGL.Math.Vec4.adds$ = function (v, s) { v[0] += s; v[1] += s; v[2] += s; v[3] += s; return v; } /** * In-place component-wise subtraction of two 4-dimensional vectors. * * @param {array} u The first addition operand. * @param {array} v The second addition operand * * @returns {array} The input vector u, where u[i] = u[i] - v[i]. */ SpiderGL.Math.Vec4.sub$ = function (u, v) { u[0] -= v[0]; u[1] -= v[1]; u[2] -= v[2]; u[3] -= v[3]; return u; } /** * In-place component-wise subtraction of a 4-dimensional vector and a scalar. * * @param {array} v The vector subtraction operand. * @param {number} s The scalar subtraction operand * * @returns {array} The input vector v, where v[i] = v[i] - s. */ SpiderGL.Math.Vec4.subs$ = function (v, s) { v[0] -= s; v[1] -= s; v[2] -= s; v[3] -= s; return v; } /** * In-place component-wise subtraction of a scalar and a 4-dimensional vector. * * @param {number} s The scalar subtraction operand * @param {array} v The vector subtraction operand. * * @returns {array} The input vector v, where v[i] = s - v[i]. */ SpiderGL.Math.Vec4.ssub$ = function (s, v) { v[0] = s - v[0]; v[1] = s - v[1]; v[2] = s - v[2]; v[3] = s - v[3]; return v; } /** * In-place component-wise multiplication of two 4-dimensional vectors. * * @param {array} u The first multiplication operand. * @param {array} v The second multiplication operand * * @returns {array} The input vector u, where u[i] = u[i] * v[i]. */ SpiderGL.Math.Vec4.mul$ = function (u, v) { u[0] *= v[0]; u[1] *= v[1]; u[2] *= v[2]; u[3] *= v[3]; return u; } /** * In-place component-wise multiplication of a 4-dimensional vector and a scalar. * * @param {array} v The first multiplication operand. * @param {number} s The second multiplication operand * * @returns {array} The input vector v, where v[i] = v[i] * s. */ SpiderGL.Math.Vec4.muls$ = function (v, s) { v[0] *= s; v[1] *= s; v[2] *= s; v[3] *= s; return v; } /** * In-place component-wise division of two 4-dimensional vectors. * * @param {array} u The numerator vector. * @param {array} v The denominator vector. * * @returns {array} The input vector u, where u[i] = u[i] / v[i]. */ SpiderGL.Math.Vec4.div$ = function (u, v) { u[0] /= v[0]; u[1] /= v[1]; u[2] /= v[2]; u[3] /= v[3]; return u; } /** * In-place component-wise division of a 4-dimensional vector by a scalar. * * @param {array} v The numerator vector. * @param {number} s The scalar denominator. * * @returns {array} The input vector v, where v[i] = v[i] / s. */ SpiderGL.Math.Vec4.divs$ = function (v, s) { v[0] /= s; v[1] /= s; v[2] /= s; v[3] /= s; return v; } /** * In-place component-wise division of a scalar by a 4-dimensional. * * @param {number} s The scalar numerator. * @param {array} v The denominator vector. * * @returns {array} The input vector v, where v[i] = s / v[i]. */ SpiderGL.Math.Vec4.sdiv$ = function (v, s) { v[0] = s / v[0]; v[1] = s / v[1]; v[2] = s / v[2]; v[3] = s / v[3]; return v; } /** * In-place 4-dimensional vector normalization. * * @param {array} v The input vector. * * @returns {array} The input vector v, where v[i] = v[i] / {@link SpiderGL.Math.Vec4.length}(v) */ SpiderGL.Math.Vec4.normalize$ = function (v) { var f = 1.0 / SpiderGL.Math.Vec4.length(v); return SpiderGL.Math.Vec4.muls$(v, f); } /*---------------------------------------------------------*/ // 3x3 matrix /*---------------------------------------------------------*/ /** * The SpiderGL.Math.Mat3 namespace. * The provided functions operate on 3x3 matrices, represented as standard JavaScript arrays of length 9. * In general, matrices are considered in column-major format. * * @namespace The SpiderGL.Math.Mat3 namespace defines operations on 3x3 matrices. */ SpiderGL.Math.Mat3 = { }; /** * Duplicates the input 3x3 matrix. * * @param {array} n The input matrix. * * @returns {array} A 9-component array r, where r[i] = m[i] (same as m.slice(0, 9)). */ SpiderGL.Math.Mat3.dup = function (m) { return m.slice(0, 9); } /** * Creates a 3x3 matrix initialized with a scalar. * * @param {number} s The input scalar. * * @returns {array} A 9-component array r, where r[i] = s. */ SpiderGL.Math.Mat3.scalar = function (s) { return [ s, s, s, s, s, s, s, s, s ]; } /** * Creates a 3x3 matrix initialized with zero. * * @returns {array} A 9-component array r, where r[i] = 0. */ SpiderGL.Math.Mat3.zero = function () { return [ 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; } /** * Creates a 3x3 matrix initialized with one. * * @returns {array} A 9-component array r, where r[i] = 1. */ SpiderGL.Math.Mat3.one = function () { return [ 1, 1, 1, 1, 1, 1, 1, 1, 1 ]; } /** * Creates a diagonal 3x3 matrix. * * @param {array} d A 3-dimensional vector * * @returns {array} A 9-component array representing a 3x3 matrix with diagonal elements set to d. */ SpiderGL.Math.Mat3.diag = function (d) { return [ d[0], 0, 0, 0, d[0], 0, 0, 0, d[0] ]; } /** * Creates an identity 3x3 matrix. * * @returns {array} A 9-component array representing an identity 3x3 matrix. */ SpiderGL.Math.Mat3.identity = function () { return [ 1, 0, 0, 0, 1, 0, 0, 0, 1 ]; } /** * Extends a 3x3 matrix to a 4x4 matrix. * * @param {array} m The input matrix. * * @returns {array} A 16-component array representing a 4x4 matrix r, with the input 3x3 matrix as tue upper-left 3x3 region with [0, 0, 0, 1] as last row and column. */ SpiderGL.Math.Mat3.to44 = function (m) { return [ m[0], m[1], m[2], 0, m[3], m[4], m[5], 0, m[6], m[7], m[8], 0, 0, 0, 0, 1 ]; } /** * Pre-multiplies a 2-dimensional vector by a column-major 3x3 matrix. * * @param {array} m The input column-major 3x3 matrix. * @param {array} v The input 2-dimensional vector. * @param {number} [z=0] The 3rd component of the input 2-dimensional vector. * * @return {array} A 2-dimensional vector r, where r = m * v. */ SpiderGL.Math.Mat3.mul2 = function (m, v, z) { z = (z == undefined) ? (0) : (z); return [ m[0]*v[0] + m[3]*v[1] + m[6]*z, m[1]*v[0] + m[4]*v[1] + m[7]*z /* , m[2]*v[0] + m[5]*v[1] + m[8]*z */ ]; } /** * Pre-multiplies a 3-dimensional vector by a column-major 3x3 matrix. * * @param {array} m The input column-major 3x3 matrix. * @param {array} v The input 3-dimensional vector. * * @return {array} A 3-dimensional vector r, where r = m * v. */ SpiderGL.Math.Mat3.mul3 = function (m, v) { return [ m[0]*v[0] + m[3]*v[1] + m[6]*v[2], m[1]*v[0] + m[4]*v[1] + m[7]*v[2], m[2]*v[0] + m[5]*v[1] + m[8]*v[2] ]; } /*---------------------------------------------------------*/ // 4x4 matrix /*---------------------------------------------------------*/ /** * The SpiderGL.Math.Mat4 namespace. * The provided functions operate on 4x4 matrices, represented as standard JavaScript arrays of length 16. * In general, matrices are considered in column-major format. * * @namespace The SpiderGL.Math.Mat4 namespace defines operations on 4x4 matrices. */ SpiderGL.Math.Mat4 = { }; /** * Duplicates the input 4x4 matrix. * * @param {array} n The input matrix. * * @returns {array} A 16-component array r, where r[i] = m[i] (same as m.slice(0, 16)). */ SpiderGL.Math.Mat4.dup = function (m) { return m.slice(0, 16); } /** * Creates a 4x4 matrix initialized with a scalar. * * @param {number} s The input scalar. * * @returns {array} A 16-component array r, where r[i] = s. */ SpiderGL.Math.Mat4.scalar = function (s) { return [ s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s ]; } /** * Creates a 4x4 matrix initialized with zero. * * @returns {array} A 16-component array r, where r[i] = 0. */ SpiderGL.Math.Mat4.zero = function () { return [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; } /** * Creates a 4x4 matrix initialized with one. * * @returns {array} A 16-component array r, where r[i] = 1. */ SpiderGL.Math.Mat4.one = function () { return [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ]; } /** * Creates a diagonal 4x4 matrix. * * @param {array} d A 4-dimensional vector * * @returns {array} A 16-component array representing a 4x4 matrix with diagonal elements set to d. */ SpiderGL.Math.Mat4.diag = function (d) { return [ d[0], 0, 0, 0, 0, d[0], 0, 0, 0, 0, d[0], 0, 0, 0, 0, d[0] ]; } /** * Creates an identity 4x4 matrix. * * @returns {array} A 16-component array representing an identity 4x4 matrix. */ SpiderGL.Math.Mat4.identity = function () { return [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ]; } /** * Extracts the upper-left 3x3 matrix from a 4x4 matrix. * * @param {array} m The input matrix. * * @returns {array} A 9-component array representing the upper-left 3x3 matrix. */ SpiderGL.Math.Mat4.to33 = function (m) { return [ m[ 0], m[ 1], m[ 2], m[ 4], m[ 5], m[ 6], m[ 8], m[ 9], m[10] ]; } /** * Gets an element of a 4x4 matrix. * * @param {array} m The input matrix. * @param {number} row The element row index. * @param {number} col The element column index. * * @returns {number} The value of the (i-th, j-th) element of m. */ SpiderGL.Math.Mat4.elem = function (m, row, col) { return m[row+col*4]; } /** * Sets an element of a 4x4 matrix. * * @param {array} m The input matrix. * @param {number} row The element row index. * @param {number} col The element column index. * @param {number} value The element value to set. */ SpiderGL.Math.Mat4.elem$ = function (m, row, col, value) { m[row+col*4] = value; } /** * Gets a row of a 4x4 matrix. * * @param {array} m The input matrix. * @param {number} row The row index. * * @returns {array} A 4-component array representing the row-th row of m. */ SpiderGL.Math.Mat4.row = function (m, row) { return [m[row+0], m[row+4], m[row+8], m[row+12]]; } /** * Sets a row of a 4x4 matrix. * * @param {array} m The input matrix. * @param {number} row The row index. * @param {array} v A 4-component array that will be copied to the row-th row of m. */ SpiderGL.Math.Mat4.row$ = function (m, row, v) { m[row+ 0] = v[0]; m[row+ 4] = v[1]; m[row+ 8] = v[2]; m[row+12] = v[3]; } /** * Gets a column of a 4x4 matrix. * * @param {array} m The input matrix. * @param {number} col The column index. * * @returns {array} A 4-component array representing the col-th column of m. */ SpiderGL.Math.Mat4.col = function (m, col) { var i = col * 4; return [m[i+0], m[i+1], m[i+2], m[i+3]]; } /** * Sets a column of a 4x4 matrix. * * @param {array} m The input matrix. * @param {number} col The column index. * @param {array} v A 4-component array that will be copied to the col-th column of m. */ SpiderGL.Math.Mat4.col$ = function (m, col, v) { var i = col * 4; m[i+0] = v[0]; m[i+1] = v[1]; m[i+2] = v[2]; m[i+3] = v[3]; } /** * Tests whether a 4x4 matrix is the identity matrix. * * @param {array} m The input matrix. * * @return {bool} True if the input matrix is the identity matrix, false otherwise. */ SpiderGL.Math.Mat4.isIdentity = function (m) { return ((m[ 0] === 1) && (m[ 1] === 0) && (m[ 2] === 0) && (m[ 3] === 0) && (m[ 4] === 0) && (m[ 5] === 1) && (m[ 6] === 0) && (m[ 7] === 0) && (m[ 8] === 0) && (m[ 9] === 0) && (m[10] === 1) && (m[11] === 0) && (m[12] === 0) && (m[13] === 0) && (m[14] === 0) && (m[15] === 1)); } /** * Component-wise negation of a 4x4 matrix. * * @param {array} m The input matrix. * * @return {array} A 4x4 matrix r, where r[i] = -m[i]. */ SpiderGL.Math.Mat4.neg = function (m) { return [ -m[ 0], -m[ 1], -m[ 2], -m[ 3], -m[ 4], -m[ 5], -m[ 6], -m[ 7], -m[ 8], -m[ 9], -m[10], -m[11], -m[12], -m[13], -m[14], -m[15] ]; } /** * Component-wise addition of two 4x4 matrices. * * @param {array} a The first input matrix. * @param {array} b The first input matrix. * * @return {array} A 4x4 matrix r, where r[i] = a[i] + b[i]. */ SpiderGL.Math.Mat4.add = function (a, b) { return [ a[ 0]+b[ 0], a[ 1]+b[ 1], a[ 2]+b[ 2], a[ 3]+b[ 3], a[ 4]+b[ 4], a[ 5]+b[ 5], a[ 6]+b[ 6], a[ 7]+b[ 7], a[ 8]+b[ 8], a[ 9]+b[ 9], a[10]+b[10], a[11]+b[11], a[12]+b[12], a[13]+b[13], a[14]+b[14], a[15]+b[15] ]; } /** * Component-wise addition of two 4x4 matrices. * * @param {array} a The first input matrix. * @param {array} b The first input matrix. * * @return {array} A 4x4 matrix r, where r[i] = a[i] - b[i]. */ SpiderGL.Math.Mat4.sub = function (a, b) { return [ a[ 0]-b[ 0], a[ 1]-b[ 1], a[ 2]-b[ 2], a[ 3]-b[ 3], a[ 4]-b[ 4], a[ 5]-b[ 5], a[ 6]-b[ 6], a[ 7]-b[ 7], a[ 8]-b[ 8], a[ 9]-b[ 9], a[10]-b[10], a[11]-b[11], a[12]-b[12], a[13]-b[13], a[14]-b[14], a[15]-b[15] ]; } /** * Multiplies of two column-major 4x4 matrices. * * @param {array} a The first input matrix. * @param {array} b The first input matrix. * * @return {array} A 4x4 matrix r, result of matrix multiplication r = a * b. */ SpiderGL.Math.Mat4.mul = function (a, b) { var a0 = a[ 0], a1 = a[ 1], a2 = a[ 2], a3 = a[ 3], a4 = a[ 4], a5 = a[ 5], a6 = a[ 6], a7 = a[ 7], a8 = a[ 8], a9 = a[ 9], a10 = a[10], a11 = a[11], a12 = a[12], a13 = a[13], a14 = a[14], a15 = a[15], b0 = b[ 0], b1 = b[ 1], b2 = b[ 2], b3 = b[ 3], b4 = b[ 4], b5 = b[ 5], b6 = b[ 6], b7 = b[ 7], b8 = b[ 8], b9 = b[ 9], b10 = b[10], b11 = b[11], b12 = b[12], b13 = b[13], b14 = b[14], b15 = b[15]; return [ a0*b0 + a4*b1 + a8*b2 + a12*b3, a1*b0 + a5*b1 + a9*b2 + a13*b3, a2*b0 + a6*b1 + a10*b2 + a14*b3, a3*b0 + a7*b1 + a11*b2 + a15*b3, a0*b4 + a4*b5 + a8*b6 + a12*b7, a1*b4 + a5*b5 + a9*b6 + a13*b7, a2*b4 + a6*b5 + a10*b6 + a14*b7, a3*b4 + a7*b5 + a11*b6 + a15*b7, a0*b8 + a4*b9 + a8*b10 + a12*b11, a1*b8 + a5*b9 + a9*b10 + a13*b11, a2*b8 + a6*b9 + a10*b10 + a14*b11, a3*b8 + a7*b9 + a11*b10 + a15*b11, a0*b12 + a4*b13 + a8*b14 + a12*b15, a1*b12 + a5*b13 + a9*b14 + a13*b15, a2*b12 + a6*b13 + a10*b14 + a14*b15, a3*b12 + a7*b13 + a11*b14 + a15*b15 ]; } /** * Component-wise multiplication of a 4x4 matrix and a scalar. * * @param {array} m The matrix operand. * @param {number} s The scalar operand. * * @returns {array} A 4x4 matrix r, where r[i] = m[i] * s. */ SpiderGL.Math.Mat4.muls = function (m, s) { return [ m[ 0]*s, m[ 1]*s, m[ 2]*s, m[ 3]*s, m[ 4]*s, m[ 5]*s, m[ 6]*s, m[ 7]*s, m[ 8]*s, m[ 9]*s, m[10]*s, m[11]*s, m[12]*s, m[13]*s, m[14]*s, m[15]*s ]; } /** * Pre-multiplies a 3-dimensional vector by a column-major 4x4 matrix. * * @param {array} m The input column-major 4x4 matrix. * @param {array} v The input 3-dimensional vector. * @param {number} [w=1] The 4th component of the input 3-dimensional vector. * * @return {array} A 3-dimensional vector r, where r = m * v. */ SpiderGL.Math.Mat4.mul3 = function (m, v, w) { w = (w == undefined) ? (1) : (w); return [ m[ 0]*v[0] + m[ 4]*v[1] + m[ 8]*v[2] + m[12]*w, m[ 1]*v[0] + m[ 5]*v[1] + m[ 9]*v[2] + m[13]*w, m[ 2]*v[0] + m[ 6]*v[1] + m[10]*v[2] + m[14]*w /* , m[ 3]*v[0] + m[ 7]*v[1] + m[11]*v[2] + m[15]*w */ ]; } /** * Pre-multiplies a 4-dimensional vector by a column-major 4x4 matrix. * * @param {array} m The input column-major 4x4 matrix. * @param {array} v The input 4-dimensional vector. * * @return {array} A 4-dimensional vector r, where r = m * v. */ SpiderGL.Math.Mat4.mul4 = function (m, v) { return [ m[ 0]*v[0] + m[ 4]*v[1] + m[ 8]*v[2] + m[12]*v[3], m[ 1]*v[0] + m[ 5]*v[1] + m[ 9]*v[2] + m[13]*v[3], m[ 2]*v[0] + m[ 6]*v[1] + m[10]*v[2] + m[14]*v[3], m[ 3]*v[0] + m[ 7]*v[1] + m[11]*v[2] + m[15]*v[3] ]; } /** * Component-wise reciprocal of a 4x4 matrix. * * @param {array} m The input matrix. * * @returns {array} A 4x4 matrix r, where r[i] = 1 / m[i]. */ SpiderGL.Math.Mat4.rcp = function (m) { return [ 1/m[ 0], 1/m[ 1], 1/m[ 2], 1/m[ 3], 1/m[ 4], 1/m[ 5], 1/m[ 6], 1/m[ 7], 1/m[ 8], 1/m[ 9], 1/m[10], 1/m[11], 1/m[12], 1/m[13], 1/m[14], 1/m[15] ]; } /** * Component-wise multiplication of two 4x4 matrices. * * @param {array} a The first matrix. * @param {array} b The second matrix. * * @returns {array} A 4x4 matrix r, where r[i] = a[i] * b[i]. */ SpiderGL.Math.Mat4.compMul = function (a, b) { return [ a[ 0]*b[ 0], a[ 1]*b[ 1], a[ 2]*b[ 2], a[ 3]*b[ 3], a[ 4]*b[ 4], a[ 5]*b[ 5], a[ 6]*b[ 6], a[ 7]*b[ 7], a[ 8]*b[ 8], a[ 9]*b[ 9], a[10]*b[10], a[11]*b[11], a[12]*b[12], a[13]*b[13], a[14]*b[14], a[15]*b[15] ]; } /** * Component-wise division of two 4x4 matrices. * * @param {array} a The first matrix. * @param {array} b The second matrix. * * @returns {array} A 4x4 matrix r, where r[i] = a[i] / b[i]. */ SpiderGL.Math.Mat4.compDiv = function (a, b) { return [ a[ 0]/b[ 0], a[ 1]/b[ 1], a[ 2]/b[ 2], a[ 3]/b[ 3], a[ 4]/b[ 4], a[ 5]/b[ 5], a[ 6]/b[ 6], a[ 7]/b[ 7], a[ 8]/b[ 8], a[ 9]/b[ 9], a[10]/b[10], a[11]/b[11], a[12]/b[12], a[13]/b[13], a[14]/b[14], a[15]/b[15] ]; } /** * Creates the transpose of a 4x4 matrix. * * @param {array} m The input matrix. * * @returns {array} A 4x4 matrix representing the transpose of m. */ SpiderGL.Math.Mat4.transpose = function (m) { return [ m[ 0], m[ 4], m[ 8], m[12], m[ 1], m[ 5], m[ 9], m[13], m[ 2], m[ 6], m[10], m[14], m[ 3], m[ 7], m[11], m[15] ]; } /** * Calculates the determinant of a 4x4 matrix. * * @param {array} m The input matrix. * * @returns {number} The determinant of m. */ SpiderGL.Math.Mat4.determinant = function (m) { var m0 = m[ 0], m1 = m[ 1], m2 = m[ 2], m3 = m[ 3], m4 = m[ 4], m5 = m[ 5], m6 = m[ 6], m7 = m[ 7], m8 = m[ 8], m9 = m[ 9], m10 = m[10], m11 = m[11], m12 = m[12], m13 = m[13], m14 = m[14], m15 = m[15]; return (m12 * m9 * m6 * m3 - m8 * m13 * m6 * m3 - m12 * m5 * m10 * m3 + m4 * m13 * m10 * m3 + m8 * m5 * m14 * m3 - m4 * m9 * m14 * m3 - m12 * m9 * m2 * m7 + m8 * m13 * m2 * m7 + m12 * m1 * m10 * m7 - m0 * m13 * m10 * m7 - m8 * m1 * m14 * m7 + m0 * m9 * m14 * m7 + m12 * m5 * m2 * m11 - m4 * m13 * m2 * m11 - m12 * m1 * m6 * m11 + m0 * m13 * m6 * m11 + m4 * m1 * m14 * m11 - m0 * m5 * m14 * m11 - m8 * m5 * m2 * m15 + m4 * m9 * m2 * m15 + m8 * m1 * m6 * m15 - m0 * m9 * m6 * m15 - m4 * m1 * m10 * m15 + m0 * m5 * m10 * m15); } /** * Calculates the inverse of a 4x4 matrix. * * @param {array} m The input matrix. * * @returns {array} A 4x4 matrix representing the inverse of m. */ SpiderGL.Math.Mat4.inverse = function (m) { var m0 = m[ 0], m1 = m[ 1], m2 = m[ 2], m3 = m[ 3], m4 = m[ 4], m5 = m[ 5], m6 = m[ 6], m7 = m[ 7], m8 = m[ 8], m9 = m[ 9], m10 = m[10], m11 = m[11], m12 = m[12], m13 = m[13], m14 = m[14], m15 = m[15]; var d = 1 / ( m12 * m9 * m6 * m3 - m8 * m13 * m6 * m3 - m12 * m5 * m10 * m3 + m4 * m13 * m10 * m3 + m8 * m5 * m14 * m3 - m4 * m9 * m14 * m3 - m12 * m9 * m2 * m7 + m8 * m13 * m2 * m7 + m12 * m1 * m10 * m7 - m0 * m13 * m10 * m7 - m8 * m1 * m14 * m7 + m0 * m9 * m14 * m7 + m12 * m5 * m2 * m11 - m4 * m13 * m2 * m11 - m12 * m1 * m6 * m11 + m0 * m13 * m6 * m11 + m4 * m1 * m14 * m11 - m0 * m5 * m14 * m11 - m8 * m5 * m2 * m15 + m4 * m9 * m2 * m15 + m8 * m1 * m6 * m15 - m0 * m9 * m6 * m15 - m4 * m1 * m10 * m15 + m0 * m5 * m10 * m15); return [ d * (m9*m14*m7-m13*m10*m7+m13*m6*m11-m5*m14*m11-m9*m6*m15+m5*m10*m15), d * (m13*m10*m3-m9*m14*m3-m13*m2*m11+m1*m14*m11+m9*m2*m15-m1*m10*m15), d * (m5*m14*m3-m13*m6*m3+m13*m2*m7-m1*m14*m7-m5*m2*m15+m1*m6*m15), d * (m9*m6*m3-m5*m10*m3-m9*m2*m7+m1*m10*m7+m5*m2*m11-m1*m6*m11), d * (m12*m10*m7-m8*m14*m7-m12*m6*m11+m4*m14*m11+m8*m6*m15-m4*m10*m15), d * (m8*m14*m3-m12*m10*m3+m12*m2*m11-m0*m14*m11-m8*m2*m15+m0*m10*m15), d * (m12*m6*m3-m4*m14*m3-m12*m2*m7+m0*m14*m7+m4*m2*m15-m0*m6*m15), d * (m4*m10*m3-m8*m6*m3+m8*m2*m7-m0*m10*m7-m4*m2*m11+m0*m6*m11), d * (m8*m13*m7-m12*m9*m7+m12*m5*m11-m4*m13*m11-m8*m5*m15+m4*m9*m15), d * (m12*m9*m3-m8*m13*m3-m12*m1*m11+m0*m13*m11+m8*m1*m15-m0*m9*m15), d * (m4*m13*m3-m12*m5*m3+m12*m1*m7-m0*m13*m7-m4*m1*m15+m0*m5*m15), d * (m8*m5*m3-m4*m9*m3-m8*m1*m7+m0*m9*m7+m4*m1*m11-m0*m5*m11), d * (m12*m9*m6-m8*m13*m6-m12*m5*m10+m4*m13*m10+m8*m5*m14-m4*m9*m14), d * (m8*m13*m2-m12*m9*m2+m12*m1*m10-m0*m13*m10-m8*m1*m14+m0*m9*m14), d * (m12*m5*m2-m4*m13*m2-m12*m1*m6+m0*m13*m6+m4*m1*m14-m0*m5*m14), d * (m4*m9*m2-m8*m5*m2+m8*m1*m6-m0*m9*m6-m4*m1*m10+m0*m5*m10) ]; } /** * Calculates the inverse transpose of the upper-left 3x3 matrix of a 4x4 matrix. * * @param {array} m The input matrix. * * @returns {array} A 3x3 matrix representing the inverse transpose of the upper-left 3x3 matrix of m. */ SpiderGL.Math.Mat4.inverseTranspose33 = function (m) { var m11 = m[ 0], m21 = m[ 1], m31 = m[ 2], m12 = m[ 4], m22 = m[ 5], m32 = m[ 6], m13 = m[ 8], m23 = m[ 9], m33 = m[10]; var d = 1 / (m11*(m33*m22 - m32*m23) - m21*(m33*m12 - m32*m13) + m31*(m23*m12 - m22*m13)); return [ d * (m33*m22 - m32*m23), d * (m32*m13 - m33*m12), d * (m23*m12 - m22*m13), d * (m31*m23 - m33*m21), d * (m33*m11 - m31*m13), d * (m21*m13 - m23*m11), d * (m32*m21 - m31*m22), d * (m31*m12 - m32*m11), d * (m22*m11 - m21*m12) ]; } /** * Calculates the trace (i.e. the sum of the diagonal elements) of a 4x4 matrix. * * @param {array} m The input matrix. * * @returns {number} The trace of m. */ SpiderGL.Math.Mat4.trace = function (m) { return (m[0] + m[5] + m[10] + m[15]); } /** * Creates a column-major 4x4 translation matrix. * The input translation vector will be placed on the 4th column of an identity matrix. * * @param {array} v A 3-dimensional vector with translation offsets. * * @returns {array} A column-major 4x4 translation matrix. */ SpiderGL.Math.Mat4.translation = function (v) { return [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, v[0], v[1], v[2], 1 ]; } /** * Creates a column-major 4x4 rotation matrix. * The returned matrix will represent a counter-clockwise rotation about the input axis by the input angle in radians. * The input axis need not to be normalized. * * @param {number} angle The counter-clockwise rotation angle, in radians. * @param {array} axis A 3-dimensional vector representing the rotation axis. * * @returns {array} A column-major 4x4 rotation matrix. */ SpiderGL.Math.Mat4.rotationAngleAxis = function (angle, axis) { var ax = SpiderGL.Math.Vec3.normalize(axis); var s = SpiderGL.Math.sin(angle); var c = SpiderGL.Math.cos(angle); var q = 1 - c; var x = ax[0]; var y = ax[1]; var z = ax[2]; var xx, yy, zz, xy, yz, zx, xs, ys, zs; xx = x * x; yy = y * y; zz = z * z; xy = x * y; yz = y * z; zx = z * x; xs = x * s; ys = y * s; zs = z * s; return [ (q * xx) + c, (q * xy) + zs, (q * zx) - ys, 0, (q * xy) - zs, (q * yy) + c, (q * yz) + xs, 0, (q * zx) + ys, (q * yz) - xs, (q * zz) + c, 0, 0, 0, 0, 1 ]; } /** * Creates a column-major 4x4 scaling matrix. * * @param {array} v The scaling amount as a 3-dimensional array. * * @returns {array} A 4x4 scaling matrix. */ SpiderGL.Math.Mat4.scaling = function (v) { return [ v[0], 0, 0, 0, 0, v[0], 0, 0, 0, 0, v[0], 0, 0, 0, 0, 1 ]; } /** * Creates a column-major 4x4 look-at matrix. * * @param {array} position The viewer's position as a 3-dimensional vector. * @param {array} target The viewer's look-at point as a 3-dimensional vector. * @param {array} position The viewer's up vector as a 3-dimensional vector. * * @returns {array} A column-major 4x4 look-at matrix. */ SpiderGL.Math.Mat4.lookAt = function (position, target, up) { var v = SpiderGL.Math.Vec3.normalize(SpiderGL.Math.Vec3.sub(target, position)); var u = SpiderGL.Math.Vec3.normalize(up); var s = SpiderGL.Math.Vec3.normalize(SpiderGL.Math.Vec3.cross(v, u)); u = SpiderGL.Math.Vec3.cross(s, v); var m = [ s[0], u[0], -v[0], 0, s[1], u[1], -v[1], 0, s[2], u[2], -v[2], 0, 0, 0, 0, 1 ]; return SpiderGL.Math.Mat4.translate$(m, SpiderGL.Math.Vec3.neg(position)); } /** * Creates a column-major 4x4 orthographic projection matrix. * * @param {array} min A 3-component array with the minimum coordinates of the parallel viewing volume. * @param {array} max A 3-component array with the maximum coordinates of the parallel viewing volume. * * @returns {array} A column-major 4x4 orthographic projection matrix. */ SpiderGL.Math.Mat4.ortho = function (min, max) { var sum = SpiderGL.Math.Vec3.add(max, min); var dif = SpiderGL.Math.Vec3.sub(max, min); return [ 2 / dif[0], 0, 0, 0, 0, 2 / dif[1], 0, 0, 0, 0, -2 / dif[2], 0, -sum[0] / dif[0], -sum[1] / dif[1], -sum[2] / dif[2], 1 ]; } /** * Creates a column-major 4x4 frustum matrix. * * @param {array} min A 3-component array with the minimum coordinates of the frustum volume. * @param {array} max A 3-component array with the maximum coordinates of the frustum volume. * * @returns {array} A column-major 4x4 frustum matrix. */ SpiderGL.Math.Mat4.frustum = function (min, max) { var sum = SpiderGL.Math.Vec3.add(max, min); var dif = SpiderGL.Math.Vec3.sub(max, min); var t = 2.0 * min[2]; return [ t / dif[0], 0, 0, 0, 0, t / dif[1], 0, 0, sum[0] / dif[0], sum[1] / dif[1], -sum[2] / dif[2], -1, 0, 0, -t * max[2] / dif[2], 0 ]; } /** * Creates a column-major 4x4 perspective projection matrix. * * @param {number} fovY The vertical field-of-view angle, in radians. * @param {number} aspectRatio The projection plane aspect ratio. * @param {number} zNear The distance of the near clipping plane. * @param {number} zFar The distance of the far clipping plane. * * @returns {array} A column-major 4x4 perspective projection matrix. */ SpiderGL.Math.Mat4.perspective = function (fovY, aspectRatio, zNear, zFar) { var a = zNear * SpiderGL.Math.tan(fovY / 2); var b = a * aspectRatio; return SpiderGL.Math.Mat4.frustum([-b, -a, zNear], [b, a, zFar]); } /** * Copies a 4x4 matrix. * * @param {array} dst The destination 4x4 matrix. * @param {array} src The source 4x4 matrix. * * @returns {array} The input matrix dst, where dst[i] = src[i]. */ SpiderGL.Math.Mat4.copy$ = function (dst, src) { for (var i=0; i<16; ++i) { dst[i] = src[i]; } return dst; } /** * Sets a 4x4 matrix as the identity matrix. * * @param {array} m The input 4x4 matrix to be set as identity. * * @returns {array} The input matrix m. */ SpiderGL.Math.Mat4.identity$ = function (m) { m[ 0] = 1; m[ 1] = 0; m[ 2] = 0; m[ 3] = 0; m[ 4] = 0; m[ 5] = 1; m[ 6] = 0; m[ 7] = 0; m[ 8] = 0; m[ 9] = 0; m[10] = 1; m[11] = 0; m[12] = 0; m[13] = 0; m[14] = 0; m[15] = 1; return m; } /** * In-place negation of a 4x4 matrix. * * @param {array} m The input 4x4 matrix. * * @returns {array} The input matrix m, where m[i] = -m[i]. */ SpiderGL.Math.Mat4.neg$ = function (m) { for (var i=0; i<16; ++i) { m[i] = -m[i]; } return m; } /** * In-place addition of two 4x4 matrices. * * @param {array} a The first 4x4 input matrix. * @param {array} b The second 4x4 input matrix. * * @returns {array} The input matrix a, where a[i] = a[i] + b[i]. */ SpiderGL.Math.Mat4.add$ = function (a, b) { for (var i=0; i<16; ++i) { a[i] += b[i]; } return a; } /** * In-place subtraction of two 4x4 matrices. * * @param {array} a The first 4x4 input matrix. * @param {array} b The second 4x4 input matrix. * * @returns {array} The input matrix a, where a[i] = a[i] - b[i]. */ SpiderGL.Math.Mat4.sub$ = function (a, b) { for (var i=0; i<16; ++i) { a[i] -= b[i]; } return a; } /** * In-place multiplication of two 4x4 matrices. * * @param {array} a The first 4x4 input matrix. * @param {array} b The second 4x4 input matrix. * * @returns {array} The input matrix a, where a = a * b. */ SpiderGL.Math.Mat4.mul$ = function (a, b) { var a0 = a[ 0], a1 = a[ 1], a2 = a[ 2], a3 = a[ 3], a4 = a[ 4], a5 = a[ 5], a6 = a[ 6], a7 = a[ 7], a8 = a[ 8], a9 = a[ 9], a10 = a[10], a11 = a[11], a12 = a[12], a13 = a[13], a14 = a[14], a15 = a[15], b0 = b[ 0], b1 = b[ 1], b2 = b[ 2], b3 = b[ 3], b4 = b[ 4], b5 = b[ 5], b6 = b[ 6], b7 = b[ 7], b8 = b[ 8], b9 = b[ 9], b10 = b[10], b11 = b[11], b12 = b[12], b13 = b[13], b14 = b[14], b15 = b[15]; a[ 0] = a0*b0 + a4*b1 + a8*b2 + a12*b3; a[ 1] = a1*b0 + a5*b1 + a9*b2 + a13*b3; a[ 2] = a2*b0 + a6*b1 + a10*b2 + a14*b3; a[ 3] = a3*b0 + a7*b1 + a11*b2 + a15*b3; a[ 4] = a0*b4 + a4*b5 + a8*b6 + a12*b7; a[ 5] = a1*b4 + a5*b5 + a9*b6 + a13*b7; a[ 6] = a2*b4 + a6*b5 + a10*b6 + a14*b7; a[ 7] = a3*b4 + a7*b5 + a11*b6 + a15*b7; a[ 8] = a0*b8 + a4*b9 + a8*b10 + a12*b11; a[ 9] = a1*b8 + a5*b9 + a9*b10 + a13*b11; a[10] = a2*b8 + a6*b9 + a10*b10 + a14*b11; a[11] = a3*b8 + a7*b9 + a11*b10 + a15*b11; a[12] = a0*b12 + a4*b13 + a8*b14 + a12*b15; a[13] = a1*b12 + a5*b13 + a9*b14 + a13*b15; a[14] = a2*b12 + a6*b13 + a10*b14 + a14*b15; a[15] = a3*b12 + a7*b13 + a11*b14 + a15*b15; return a; } /** * In-place subtraction of a 4x4 matrix and a scalar. * * @param {array} m The 4x4 input matrix. * @param {number} s The input scalar. * * @returns {array} The input matrix m, where m[i] = m[i] * s. */ SpiderGL.Math.Mat4.muls$ = function (m, s) { for (var i=0; i<16; ++i) { m[i] *= s; } return m; } /** * In-place component-wise multiplication of two 4x4 matrices. * * @param {array} a The first 4x4 input matrix. * @param {array} b The second 4x4 input matrix. * * @returns {array} The input matrix a, where a[i] = a[i] * b[i]. */ SpiderGL.Math.Mat4.compMul$ = function (a, b) { for (var i=0; i<16; ++i) { a[i] *= b[i]; } return a; } /** * In-place component-wise division of two 4x4 matrices. * * @param {array} a The first 4x4 input matrix. * @param {array} b The second 4x4 input matrix. * * @returns {array} The input matrix a, where a[i] = a[i] / b[i]. */ SpiderGL.Math.Mat4.compDiv$ = function (a, b) { for (var i=0; i<16; ++i) { a[i] /= b[i]; } return a; } /** * In-place transpose of a 4x4 matrix. * * @param {array} m The 4x4 input matrix. * * @returns {array} The transposed input matrix m. */ SpiderGL.Math.Mat4.transpose$ = function (m) { var t; t = m[ 1]; m[ 1] = m[ 4]; m[ 4] = t; t = m[ 2]; m[ 2] = m[ 8]; m[ 8] = t; t = m[ 3]; m[ 3] = m[12]; m[12] = t; t = m[ 6]; m[ 6] = m[ 9]; m[ 9] = t; t = m[ 7]; m[ 7] = m[13]; m[13] = t; t = m[11]; m[11] = m[14]; m[14] = t; return m; } /** * In-place inversion of a 4x4 matrix. * * @param {array} m The 4x4 input matrix. * * @returns {array} The inverted input matrix m. */ SpiderGL.Math.Mat4.invert$ = function (m) { var m0 = m[ 0], m1 = m[ 1], m2 = m[ 2], m3 = m[ 3], m4 = m[ 4], m5 = m[ 5], m6 = m[ 6], m7 = m[ 7], m8 = m[ 8], m9 = m[ 9], m10 = m[10], m11 = m[11], m12 = m[12], m13 = m[13], m14 = m[14], m15 = m[15]; var d = 1.0 / ( m12 * m9 * m6 * m3 - m8 * m13 * m6 * m3 - m12 * m5 * m10 * m3 + m4 * m13 * m10 * m3 + m8 * m5 * m14 * m3 - m4 * m9 * m14 * m3 - m12 * m9 * m2 * m7 + m8 * m13 * m2 * m7 + m12 * m1 * m10 * m7 - m0 * m13 * m10 * m7 - m8 * m1 * m14 * m7 + m0 * m9 * m14 * m7 + m12 * m5 * m2 * m11 - m4 * m13 * m2 * m11 - m12 * m1 * m6 * m11 + m0 * m13 * m6 * m11 + m4 * m1 * m14 * m11 - m0 * m5 * m14 * m11 - m8 * m5 * m2 * m15 + m4 * m9 * m2 * m15 + m8 * m1 * m6 * m15 - m0 * m9 * m6 * m15 - m4 * m1 * m10 * m15 + m0 * m5 * m10 * m15); m[ 0] = d * (m9*m14*m7-m13*m10*m7+m13*m6*m11-m5*m14*m11-m9*m6*m15+m5*m10*m15); m[ 1] = d * (m13*m10*m3-m9*m14*m3-m13*m2*m11+m1*m14*m11+m9*m2*m15-m1*m10*m15); m[ 2] = d * (m5*m14*m3-m13*m6*m3+m13*m2*m7-m1*m14*m7-m5*m2*m15+m1*m6*m15); m[ 3] = d * (m9*m6*m3-m5*m10*m3-m9*m2*m7+m1*m10*m7+m5*m2*m11-m1*m6*m11); m[ 4] = d * (m12*m10*m7-m8*m14*m7-m12*m6*m11+m4*m14*m11+m8*m6*m15-m4*m10*m15); m[ 5] = d * (m8*m14*m3-m12*m10*m3+m12*m2*m11-m0*m14*m11-m8*m2*m15+m0*m10*m15); m[ 6] = d * (m12*m6*m3-m4*m14*m3-m12*m2*m7+m0*m14*m7+m4*m2*m15-m0*m6*m15); m[ 7] = d * (m4*m10*m3-m8*m6*m3+m8*m2*m7-m0*m10*m7-m4*m2*m11+m0*m6*m11); m[ 8] = d * (m8*m13*m7-m12*m9*m7+m12*m5*m11-m4*m13*m11-m8*m5*m15+m4*m9*m15); m[ 9] = d * (m12*m9*m3-m8*m13*m3-m12*m1*m11+m0*m13*m11+m8*m1*m15-m0*m9*m15); m[10] = d * (m4*m13*m3-m12*m5*m3+m12*m1*m7-m0*m13*m7-m4*m1*m15+m0*m5*m15); m[11] = d * (m8*m5*m3-m4*m9*m3-m8*m1*m7+m0*m9*m7+m4*m1*m11-m0*m5*m11); m[12] = d * (m12*m9*m6-m8*m13*m6-m12*m5*m10+m4*m13*m10+m8*m5*m14-m4*m9*m14); m[13] = d * (m8*m13*m2-m12*m9*m2+m12*m1*m10-m0*m13*m10-m8*m1*m14+m0*m9*m14); m[14] = d * (m12*m5*m2-m4*m13*m2-m12*m1*m6+m0*m13*m6+m4*m1*m14-m0*m5*m14); m[15] = d * (m4*m9*m2-m8*m5*m2+m8*m1*m6-m0*m9*m6-m4*m1*m10+m0*m5*m10); return m; } /** * In-place column-major translation of a 4x4 matrix. * * @param {array} m The 4x4 input matrix. * @param {array} v The 3-dimensional translation vector. * * @returns {array} The translated input matrix m with the same result as m = m * t, where t is a translation matrix. */ SpiderGL.Math.Mat4.translate$ = function (m, v) { var x = v[0], y = v[1], z = v[2]; m[12] = m[ 0]*x + m[ 4]*y + m[ 8]*z + m[12]; m[13] = m[ 1]*x + m[ 5]*y + m[ 9]*z + m[13]; m[14] = m[ 2]*x + m[ 6]*y + m[10]*z + m[14]; m[15] = m[ 3]*x + m[ 7]*y + m[11]*z + m[15]; return m; } /** * In-place column-major rotation of a 4x4 matrix. * The input matrix m will be post-multiplied by a matrix r representing a counter-clockwise rotation about the input axis by the input angle in radians. * The input axis need not to be normalized. * * @param {array} m The input 4x4 matrix. * @param {number} angle The counter-clockwise rotation angle, in radians. * @param {array} axis A 3-dimensional vector representing the rotation axis. * * @returns {array} The rotated input matrix m with the same result as m = m * r, where r is a rotation matrix. */ SpiderGL.Math.Mat4.rotateAngleAxis$ = function (m, angle, axis) { var r = SpiderGL.Math.Mat4.rotationAngleAxis(angle, axis); return SpiderGL.Math.Mat4.mul$(m, r); } /** * In-place column-major scaling of a 4x4 matrix. * * @param {array} m The 4x4 input matrix. * @param {array} v The scaling amount as a 3-dimensional array. * * @returns {array} The scaled input matrix m with the same result as m = m * s, where s is a scaling matrix. */ SpiderGL.Math.Mat4.scale$ = function (m, v) { var x = v[0], y = v[1], z = v[2]; m[ 0] *= x; m[ 1] *= x; m[ 2] *= x; m[ 3] *= x; m[ 4] *= y; m[ 5] *= y; m[ 6] *= y; m[ 7] *= y; m[ 8] *= z; m[ 9] *= z; m[10] *= z; m[11] *= z; return m; } /*---------------------------------------------------------*/ // quaternion /*---------------------------------------------------------*/ /** * The SpiderGL.Math.Quat namespace. * The provided functions operate on quaternions, represented as standard JavaScript arrays of length 4. * * @namespace The SpiderGL.Math.Quat namespace defines operations on quaternions. */ SpiderGL.Math.Quat = { }; /** * Duplicates the input quaternion. * * @param {array} n The input quaternion. * * @returns {array} A 4-component array r, where r[i] = q[i] (same as q.slice(0, 4)). */ SpiderGL.Math.Quat.dup = function (q) { return q.slice(0, 4); } SpiderGL.Math.Quat.identity = function (q) { return [0, 0, 0, 1]; } SpiderGL.Math.Quat.inverse = function (q) { return [-q[0], -q[1], -q[2], q[3]]; } SpiderGL.Math.Quat.mul = function (p, q) { var px = p[0], py = p[1], pz = p[2], pw = p[3]; var qx = q[0], qy = q[1], qz = q[2], qw = q[3]; return [ px*qw + pw*qx + pz*qy - py*qz, py*qw + pw*qy + px*qz - pz*qx, pz*qw + pw*qz + py*qx - px*qy, pw*qw - px*qx - py*qy - pz*qz ]; } SpiderGL.Math.Quat.muls = function (q, s) { return [q[0]*s, q[1]*s, q[2]*s, q[3]*s]; } SpiderGL.Math.Quat.normalize = function (q) { var s = 1 / SpiderGL.Math.sqrt(q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3]); return SpiderGL.Math.Quat.muls(q, s); } SpiderGL.Math.Quat.from33 = function (m) { var m00 = m[0], m10 = m[1], m20 = m[2]; var m01 = m[3], m11 = m[4], m21 = m[5]; var m02 = m[6], m12 = m[7], m22 = m[8]; var t = m00 + m11 + m22; var s; if (t > 0) { t = t + 1; s = 0.5 / SpiderGL.Math.sqrt(t); return [ (m21 - m12) * s, (m02 - m20) * s, (m10 - m01) * s, t * s ]; } else if ((m00 > m11) && (m00 > m22)) { t = m00 - m11 - m22 + 1; s = 0.5 / SpiderGL.Math.sqrt(t); return [ t * s, (m10 + m01) * s, (m02 + m20) * s, (m21 - m12) * s, ]; } else if (m11 > m22) { t = -m00 + m11 - m22 + 1; s = 0.5 / SpiderGL.Math.sqrt(t); return [ (m10 + m01) * s, t * s, (m21 + m12) * s, (m02 - m20) * s ]; } else { t = -m00 - m11 + m22 + 1; s = 0.5 / SpiderGL.Math.sqrt(t); return [ (m02 + m20) * s, (m21 + m12) * s, t * s, (m10 - m01) * s ]; } return null; } SpiderGL.Math.Quat.to33 = function (q) { var x = q[0], y = q[1], z = q[2], w = q[3]; var xx = x*x, xy = x*y, xz = x*z, xw = x*w; var yy = y*y, yz = y*z, yw = y*w; var zz = z*z, zw = z*w; return [ 1 - 2 * ( yy + zz ), 2 * ( xy + zw ), 2 * ( xz - yw ), 2 * ( xy - zw ), 1 - 2 * ( xx + zz ), 2 * ( yz + xw ), 2 * ( xz + yw ), 2 * ( yz - xw ), 1 - 2 * ( xx + yy ) ]; } SpiderGL.Math.Quat.from44 = function (m) { return SpiderGL.Math.Quat.from33(SpiderGL.Math.Mat4.to33(m)); } SpiderGL.Math.Quat.to44 = function (q) { return SpiderGL.Math.Mat3.to44(SpiderGL.Math.Quat.to33(q)); } SpiderGL.Math.Quat.fromAngleAxis = function (angle, axis) { return [0, 0, 0, 1]; } SpiderGL.Math.Quat.toAngleAxis = function (q) { return [0, 0, 0, 1]; } SpiderGL.Math.Quat.fromEulerAngles = function (x, y, z) { return [0, 0, 0, 1]; } SpiderGL.Math.Quat.toEulerAngles = function (q) { return [0, 0, 0, 1]; } SpiderGL.Math.Quat.copy$ = function (p, q) { p[0] = q[0]; p[1] = q[1]; p[2] = q[2]; p[3] = q[3]; return p; } SpiderGL.Math.Quat.identity$ = function (q) { q[0] = 0; q[1] = 0; q[2] = 0; q[3] = 1; return q; } SpiderGL.Math.Quat.invert$ = function (q) { q[0] = -q[0]; q[1] = -q[1]; q[2] = -q[2]; return q; } SpiderGL.Math.Quat.mul$ = function (q) { var px = p[0], py = p[1], pz = p[2], pw = p[3]; var qx = q[0], qy = q[1], qz = q[2], qw = q[3]; q[0] = px*qw + pw*qx + pz*qy - py*qz; q[1] = py*qw + pw*qy + px*qz - pz*qx; q[2] = pz*qw + pw*qz + py*qx - px*qy; q[3] = pw*qw - px*qx - py*qy - pz*qz; return q; } SpiderGL.Math.Quat.muls$ = function (q, s) { q[0] *= s; q[1] *= s; q[2] *= s; q[3] *= s; return q; } SpiderGL.Math.Quat.normalize$ = function (q) { var s = 1 / SpiderGL.Math.sqrt(q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3]); return SpiderGL.Math.Quat.muls$(q, s); } SpiderGL.Math.project = function (xyzw, modelViewProjectionMatrix, viewport, depthRange) { var v3 = SpiderGL.Math.Vec3; var m4 = SpiderGL.Math.Mat4; var r = m4.mul4(modelViewProjectionMatrix, xyzw); var invW = 1 / r[3]; r[3] = invW; v3.muls$(r, invW / 2); v3.adds$(r, 0.5); v3.mul$(r, [viewport[2], viewport[3], depthRange[1] - depthRange[0]]); v3.add$(r, [viewport[0], viewport[1], depthRange[0]]); return r; }; SpiderGL.Math.unproject = function (xyz, modelViewProjectionMatrixInverse, viewport, depthRange) { var v3 = SpiderGL.Math.Vec3; var m4 = SpiderGL.Math.Mat4; var r = v3.to4(xyz, 1.0); v3.sub$(r, [viewport[0], viewport[1], depthRange[0]]); v3.div$(r, [viewport[2], viewport[3], depthRange[1] - depthRange[0]]); v3.muls$(r, 2); v3.subs$(r, 1); r = m4.mul4(modelViewProjectionMatrixInverse, r); var invW = 1 / r[3]; r[3] = invW; v3.muls$(r, invW); return r; };