diff --git a/README.md b/README.md index 7f3c17e..2b63f13 100644 --- a/README.md +++ b/README.md @@ -28,32 +28,44 @@ var scale = require('gl-vec3/scale') - [add()](#addoutvec3avec3bvec3) - [angle()](#angleavec3bvec3) - [clone()](#cloneavec3) + - [ceil()](#ceiloutvec3-avec3) - [copy()](#copyoutvec3avec3) - [create()](#create) - [cross()](#crossoutvec3avec3bvec3) - [distance()](#distanceavec3bvec3) + - [dist()](#distanceavec3bvec3) - [divide()](#divideoutvec3avec3bvec3) + - [div()](#divideoutvec3avec3bvec3) - [dot()](#dotavec3bvec3) + - [equals()](#equalsavec3-bvec3) + - [exactEquals()](#exactequalsavec3-bvec3) + - [floor()](#flooroutvec3-avec3) - [forEach()](#foreachaarraystridenumberoffsetnumbercountnumberfnfunctionargobject) - [fromValues()](#fromvaluesxnumberynumberznumber) - [inverse()](#inverseoutvec3avec3) - [length()](#lengthavec3) + - [len()](#lengthavec3) - [lerp()](#lerpoutvec3avec3bvec3tnumber) - [max()](#maxoutvec3avec3bvec3) - [min()](#minoutvec3avec3bvec3) - [multiply()](#multiplyoutvec3avec3bvec3) + - [mul()](#multiplyoutvec3avec3bvec3) - [negate()](#negateoutvec3avec3) - [normalize()](#normalizeoutvec3avec3) - [random()](#randomoutvec3scalenumber) - [rotateX()](#rotatexoutvec3avec3bvec3cnumber) - [rotateY()](#rotateyoutvec3avec3bvec3cnumber) - [rotateZ()](#rotatezoutvec3avec3bvec3cnumber) + - [round()](#roundoutvec3-avec3) - [scale()](#scaleoutvec3avec3bnumber) - [scaleAndAdd()](#scaleandaddoutvec3avec3bvec3scalenumber) - [set()](#setoutvec3xnumberynumberznumber) - [squaredDistance()](#squareddistanceavec3bvec3) + - [sqrDist()](#squareddistanceavec3bvec3) - [squaredLength()](#squaredlengthavec3) + - [sqrLen()](#squaredlengthavec3) - [subtract()](#subtractoutvec3avec3bvec3) + - [sub()](#subtractoutvec3avec3bvec3) - [transformMat3()](#transformmat3outvec3avec3mmat4) - [transformMat4()](#transformmat4outvec3avec3mmat4) - [transformQuat()](#transformquatoutvec3avec3qquat) @@ -66,6 +78,10 @@ var scale = require('gl-vec3/scale') Get the angle between two 3D vectors +## ceil(out:vec3, a:vec3) + + `Math.ceil` the components of a vec3 + ## clone(a:vec3) Creates a new vec3 initialized with values from an existing vector @@ -84,16 +100,28 @@ var scale = require('gl-vec3/scale') ## distance(a:vec3, b:vec3) - Calculates the euclidian distance between two vec3's + Calculates the euclidian distance between two vec3's. Aliased as `dist` ## divide(out:vec3, a:vec3, b:vec3) - Divides two vec3's + Divides two vec3's. Aliased as `div` ## dot(a:vec3, b:vec3) Calculates the dot product of two vec3's +## equals(a:vec3, b:vec3) + + Returns whether or not the vectors have approximately the same elements in the same position. + +## exactEquals(a:vec3, b:vec3) + + Returns whether or not the vectors exactly have the same elements in the same position (when compared with ===) + +## floor(out:vec3, a:vec3) + + `Math.floor` the components of a vec3 + ## forEach(a:Array, stride:Number, offset:Number, count:Number, fn:Function, [arg]:Object) Perform some operation over an array of vec3s. @@ -108,7 +136,7 @@ var scale = require('gl-vec3/scale') ## length(a:vec3) - Calculates the length of a vec3 + Calculates the length of a vec3. Aliased as `len` ## lerp(out:vec3, a:vec3, b:vec3, t:Number) @@ -124,7 +152,7 @@ var scale = require('gl-vec3/scale') ## multiply(out:vec3, a:vec3, b:vec3) - Multiplies two vec3's + Multiplies two vec3's. Aliased as `mul` ## negate(out:vec3, a:vec3) @@ -150,6 +178,10 @@ var scale = require('gl-vec3/scale') Rotate a 3D vector around the z-axis +## round(out:vec3, a:vec3) + + `Math.round` the components of a vec3 + ## scale(out:vec3, a:vec3, b:Number) Scales a vec3 by a scalar number @@ -164,15 +196,15 @@ var scale = require('gl-vec3/scale') ## squaredDistance(a:vec3, b:vec3) - Calculates the squared euclidian distance between two vec3's + Calculates the squared euclidian distance between two vec3's. Aliased as `sqrDist` ## squaredLength(a:vec3) - Calculates the squared length of a vec3 + Calculates the squared length of a vec3. Aliased as `sqrLen` ## subtract(out:vec3, a:vec3, b:vec3) - Subtracts vector b from vector a + Subtracts vector b from vector a. Aliased as `sub` ## transformMat3(out:vec3, a:vec3, m:mat4) @@ -189,4 +221,4 @@ var scale = require('gl-vec3/scale') ## License -[zlib](http://en.wikipedia.org/wiki/Zlib_License). See [LICENSE.md](https://github.com/stackgl/gl-vec3/blob/master/LICENSE.md) for details. \ No newline at end of file +[zlib](http://en.wikipedia.org/wiki/Zlib_License). See [LICENSE.md](https://github.com/stackgl/gl-vec3/blob/master/LICENSE.md) for details. diff --git a/ceil.js b/ceil.js new file mode 100644 index 0000000..3aa8c84 --- /dev/null +++ b/ceil.js @@ -0,0 +1,15 @@ +module.exports = ceil + +/** + * Math.ceil the components of a vec3 + * + * @param {vec3} out the receiving vector + * @param {vec3} a vector to ceil + * @returns {vec3} out + */ +function ceil(out, a) { + out[0] = Math.ceil(a[0]) + out[1] = Math.ceil(a[1]) + out[2] = Math.ceil(a[2]) + return out +} diff --git a/dist.js b/dist.js new file mode 100644 index 0000000..fc548d9 --- /dev/null +++ b/dist.js @@ -0,0 +1 @@ +module.exports = require('./distance') diff --git a/div.js b/div.js new file mode 100644 index 0000000..ffdd25e --- /dev/null +++ b/div.js @@ -0,0 +1 @@ +module.exports = require('./divide') diff --git a/epsilon.js b/epsilon.js new file mode 100644 index 0000000..9bf3227 --- /dev/null +++ b/epsilon.js @@ -0,0 +1 @@ +module.exports = 0.000001 diff --git a/equals.js b/equals.js new file mode 100644 index 0000000..2afdfe1 --- /dev/null +++ b/equals.js @@ -0,0 +1,22 @@ +module.exports = equals + +var EPSILON = require('./epsilon') + +/** + * Returns whether or not the vectors have approximately the same elements in the same position. + * + * @param {vec3} a The first vector. + * @param {vec3} b The second vector. + * @returns {Boolean} True if the vectors are equal, false otherwise. + */ +function equals(a, b) { + var a0 = a[0] + var a1 = a[1] + var a2 = a[2] + var b0 = b[0] + var b1 = b[1] + var b2 = b[2] + return (Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && + Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && + Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2))) +} diff --git a/exactEquals.js b/exactEquals.js new file mode 100644 index 0000000..d8deae6 --- /dev/null +++ b/exactEquals.js @@ -0,0 +1,12 @@ +module.exports = exactEquals + +/** + * Returns whether or not the vectors exactly have the same elements in the same position (when compared with ===) + * + * @param {vec3} a The first vector. + * @param {vec3} b The second vector. + * @returns {Boolean} True if the vectors are equal, false otherwise. + */ +function exactEquals(a, b) { + return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] +} diff --git a/floor.js b/floor.js new file mode 100644 index 0000000..1dc0413 --- /dev/null +++ b/floor.js @@ -0,0 +1,15 @@ +module.exports = floor + +/** + * Math.floor the components of a vec3 + * + * @param {vec3} out the receiving vector + * @param {vec3} a vector to floor + * @returns {vec3} out + */ +function floor(out, a) { + out[0] = Math.floor(a[0]) + out[1] = Math.floor(a[1]) + out[2] = Math.floor(a[2]) + return out +} diff --git a/index.js b/index.js index f74c16f..8d4d2b9 100644 --- a/index.js +++ b/index.js @@ -1,22 +1,35 @@ module.exports = { - create: require('./create') + EPSILON: require('./epsilon') + , create: require('./create') , clone: require('./clone') , angle: require('./angle') , fromValues: require('./fromValues') , copy: require('./copy') , set: require('./set') + , equals: require('./equals') + , exactEquals: require('./exactEquals') , add: require('./add') , subtract: require('./subtract') + , sub: require('./sub') , multiply: require('./multiply') + , mul: require('./mul') , divide: require('./divide') + , div: require('./div') , min: require('./min') , max: require('./max') + , floor: require('./floor') + , ceil: require('./ceil') + , round: require('./round') , scale: require('./scale') , scaleAndAdd: require('./scaleAndAdd') , distance: require('./distance') + , dist: require('./dist') , squaredDistance: require('./squaredDistance') + , sqrDist: require('./sqrDist') , length: require('./length') + , len: require('./len') , squaredLength: require('./squaredLength') + , sqrLen: require('./sqrLen') , negate: require('./negate') , inverse: require('./inverse') , normalize: require('./normalize') @@ -31,4 +44,4 @@ module.exports = { , rotateY: require('./rotateY') , rotateZ: require('./rotateZ') , forEach: require('./forEach') -} \ No newline at end of file +} diff --git a/len.js b/len.js new file mode 100644 index 0000000..fbebab2 --- /dev/null +++ b/len.js @@ -0,0 +1 @@ +module.exports = require('./length') diff --git a/mul.js b/mul.js new file mode 100644 index 0000000..ed63273 --- /dev/null +++ b/mul.js @@ -0,0 +1 @@ +module.exports = require('./multiply') diff --git a/package.json b/package.json index dd4657c..a870a72 100644 --- a/package.json +++ b/package.json @@ -13,10 +13,12 @@ ], "dependencies": {}, "devDependencies": { - "dox": "git://github.com/hughsk/dox#api-context" + "dox": "git://github.com/hughsk/dox#api-context", + "tape": "^4.8.0" }, "scripts": { - "get-docs": "cat *.js | dox --api" + "get-docs": "cat *.js | dox --api", + "test": "node test/index.js" }, "keywords": [ "gl-matrix", diff --git a/round.js b/round.js new file mode 100644 index 0000000..681e927 --- /dev/null +++ b/round.js @@ -0,0 +1,15 @@ +module.exports = round + +/** + * Math.round the components of a vec3 + * + * @param {vec3} out the receiving vector + * @param {vec3} a vector to round + * @returns {vec3} out + */ +function round(out, a) { + out[0] = Math.round(a[0]) + out[1] = Math.round(a[1]) + out[2] = Math.round(a[2]) + return out +} diff --git a/sqrDist.js b/sqrDist.js new file mode 100644 index 0000000..4040002 --- /dev/null +++ b/sqrDist.js @@ -0,0 +1 @@ +module.exports = require('./squaredDistance') diff --git a/sqrLen.js b/sqrLen.js new file mode 100644 index 0000000..ae5f355 --- /dev/null +++ b/sqrLen.js @@ -0,0 +1 @@ +module.exports = require('./squaredLength') diff --git a/sub.js b/sub.js new file mode 100644 index 0000000..71deea1 --- /dev/null +++ b/sub.js @@ -0,0 +1 @@ +module.exports = require('./subtract') diff --git a/test/index.js b/test/index.js new file mode 100644 index 0000000..b48f006 --- /dev/null +++ b/test/index.js @@ -0,0 +1,300 @@ +var test = require('tape') +var vec3 = require('../') +var EPSILON = require('../epsilon') + +test('add', function (t) { + var result = vec3.add([], [0, 1, 2], [3, 4, 5]) + t.deepEqual(result, [3, 5, 7]) + t.end() +}) + +test('angle', function (t) { + var result = vec3.angle([3, 4, 5], [6, 7, 8]) + t.ok(Math.abs(0.08523986989116927 - result) < EPSILON) + t.end() +}) + +test('ceil', function (t) { + var result = vec3.ceil([], [5.2, 6.5, 7.9]) + t.deepEqual(result, [6, 7, 8]) + t.end() +}) + +test('clone', function (t) { + var result = vec3.clone([5, 6, 7]) + t.deepEqual(result, [5, 6, 7]) + t.end() +}) + +test('copy', function (t) { + var result = vec3.copy([], [5, 6, 7]) + t.deepEqual(result, [5, 6, 7]) + t.end() +}) + +test('create', function (t) { + var result = vec3.create() + t.deepEqual(result, [0, 0, 0]) + t.end() +}) + +test('cross', function (t) { + var result = vec3.cross([], [3, 4, 5], [6, 7, 8]) + t.deepEqual(result, [-3, 6, -3]) + t.end() +}) + +test('distance', function (t) { + var result = vec3.distance([1, 2, 3], [4, 6, 7]) + t.ok(Math.abs(result - 6.4031242374328485) < EPSILON) + t.end() +}) + +test('dist', function (t) { + var result = vec3.dist([1, 2, 3], [4, 6, 7]) + t.ok(Math.abs(result - 6.4031242374328485) < EPSILON) + t.end() +}) + +test('divide', function (t) { + var result = vec3.divide([], [8, 4, 2], [2, 1, 0.5]) + t.deepEqual(result, [4, 4, 4]) + t.end() +}) + +test('div', function (t) { + var result = vec3.div([], [8, 4, 2], [2, 1, 0.5]) + t.deepEqual(result, [4, 4, 4]) + t.end() +}) + +test('dot', function (t) { + var result = vec3.dot([3, 4, 5], [6, 7, 8]) + t.deepEqual(result, 86) + t.end() +}) + +test('equals', function (t) { + t.ok(vec3.equals([3 + EPSILON, 5 - EPSILON, 4 + EPSILON], [3, 5, 4])) + t.notOk(vec3.equals([3 + EPSILON * 10, 5, 4], [3, 5, 4])) + t.notOk(vec3.equals([3, 5 - EPSILON * 10, 4], [3, 5, 4])) + t.notOk(vec3.equals([3, 5, 4 + EPSILON * 10], [3, 5, 4])) + t.end() +}) + +test('exactEquals', function (t) { + t.ok(vec3.exactEquals([3, 5, 4], [3, 5, 4])) + t.notOk(vec3.exactEquals([3 + EPSILON, 5, 4], [3, 5, 4])) + t.notOk(vec3.exactEquals([3, 5 + EPSILON, 4], [3, 5, 4])) + t.notOk(vec3.exactEquals([3, 5, 4 + EPSILON], [3, 5, 4])) + t.end() +}) + +test('floor', function (t) { + var result = vec3.floor([], [5.2, 6.6, 7.9]) + t.deepEqual(result, [5, 6, 7]) + t.end() +}) + +test('forEach', function (t) { + var a = [null, + 0, 1, 2, null, + 3, 4, 5, null + ] + + function addConstant (out, a, val) { + out[0] = a[0] + val + out[1] = a[1] + val + out[2] = a[2] + val + return out + } + + vec3.forEach(a, 4, 1, 2, addConstant, 7) + + t.deepEqual(a, [null, 7, 8, 9, null, 10, 11, 12, null]) + t.end() +}) + +test('fromValues', function (t) { + var result = vec3.fromValues(2, 3, 4) + t.deepEqual(result, [2, 3, 4]) + t.end() +}) + +test('inverse', function (t) { + var result = vec3.inverse([], [2, 4, 8]) + t.deepEqual(result, [0.5, 0.25, 0.125]) + t.end() +}) + +test('length', function (t) { + var result = vec3.length([3, 4, 5]) + t.ok(Math.abs(result - 7.0710678118654755) < EPSILON) + t.end() +}) + +test('len', function (t) { + var result = vec3.len([3, 4, 5]) + t.ok(Math.abs(result - 7.0710678118654755) < EPSILON) + t.end() +}) + +test('lerp', function (t) { + var result = vec3.lerp([], [3, 4, 5], [6, 7, 8], 0.25) + t.deepEqual(result, [3.75, 4.75, 5.75]) + t.end() +}) + +test('max', function (t) { + var result = vec3.max([], [3, 7, 2], [5, 6, 4]) + t.deepEqual(result, [5, 7, 4]) + t.end() +}) + +test('min', function (t) { + var result = vec3.min([], [3, 7, 8], [5, 6, 2]) + t.deepEqual(result, [3, 6, 2]) + t.end() +}) + +test('multiply', function (t) { + var result = vec3.multiply([], [3, 4, 5], [6, 7, 8]) + t.deepEqual(result, [18, 28, 40]) + t.end() +}) + +test('mul', function (t) { + var result = vec3.mul([], [3, 4, 5], [6, 7, 8]) + t.deepEqual(result, [18, 28, 40]) + t.end() +}) + +test('negate', function (t) { + var result = vec3.negate([], [3, 4, 5]) + t.deepEqual(result, [-3, -4, -5]) + t.end() +}) + +test('normalize', function (t) { + var result = vec3.normalize([], [3, 4, 5]) + t.ok(Math.abs(result[0] - 0.4242640687119285) < EPSILON) + t.ok(Math.abs(result[1] - 0.565685424949238) < EPSILON) + t.ok(Math.abs(result[2] - 0.7071067811865475) < EPSILON) + t.end() +}) + +test('random', function (t) { + var result = vec3.random([], 5) + for (var i = 0; i < 10; i++) { + var len = Math.sqrt(result[0] * result[0] + result[1] * result[1] + result[2] * result[2]) + t.ok(Math.abs(5 - len) <= EPSILON) + } + t.end() +}) + +test('rotateX', function (t) { + var result = vec3.rotateX([], [3, 4, 5], [6, 7, 8], Math.PI) + t.deepEqual(result, [3, 10, 11]) + t.end() +}) + +test('rotateY', function (t) { + var result = vec3.rotateY([], [3, 4, 5], [6, 7, 8], Math.PI) + t.deepEqual(result, [9, 4, 11]) + t.end() +}) + +test('rotateZ', function (t) { + var result = vec3.rotateZ([], [3, 4, 5], [6, 7, 8], Math.PI) + t.deepEqual(result, [9, 10, 5]) + t.end() +}) + +test('scale', function (t) { + var result = vec3.scale([], [3, 4, 5], 2) + t.deepEqual(result, [6, 8, 10]) + t.end() +}) + +test('scaleAndAdd', function (t) { + var result = vec3.scaleAndAdd([], [3, 4, 5], [6, 7, 8], 2) + t.deepEqual(result, [15, 18, 21]) + t.end() +}) + +test('round', function (t) { + var result = vec3.round([], [5.2, 6.6, 8.5]) + t.deepEqual(result, [5, 7, 9]) + t.end() +}) + +test('set', function (t) { + var result = vec3.set([], 3, 4, 5) + t.deepEqual(result, [3, 4, 5]) + t.end() +}) + +test('squaredDistance', function (t) { + var result = vec3.squaredDistance([3, 4, 5], [6, 7, 8]) + t.deepEqual(result, 27) + t.end() +}) + +test('sqrDist', function (t) { + var result = vec3.sqrDist([3, 4, 5], [6, 7, 8]) + t.deepEqual(result, 27) + t.end() +}) + +test('squaredLength', function (t) { + var result = vec3.squaredLength([3, 4, 5]) + t.deepEqual(result, 50) + t.end() +}) + +test('sqrLen', function (t) { + var result = vec3.sqrLen([3, 4, 5]) + t.deepEqual(result, 50) + t.end() +}) + +test('subtract', function (t) { + var result = vec3.subtract([], [3, 4, 5], [6, 7, 8]) + t.deepEqual(result, [-3, -3, -3]) + t.end() +}) + +test('sub', function (t) { + var result = vec3.subtract([], [3, 4, 5], [6, 7, 8]) + t.deepEqual(result, [-3, -3, -3]) + t.end() +}) + +test('transformMat3', function (t) { + var result = vec3.transformMat3([], [3, 4, 5], [ + 5, 6, 7, + 8, 9, 10, + 11, 12, 13 + ]) + t.deepEqual(result, [102, 114, 126]) + t.end() +}) + +test('transformMat4', function (t) { + var result = vec3.transformMat4([], [3, 4, 5], [ + 5, 6, 7, 8, + 9, 10, 11, 12, + 13, 14, 15, 16, + 17, 18, 19, 20 + ]) + t.ok(Math.abs(0.7732558139534884 - result[0]) < EPSILON) + t.ok(Math.abs(0.8488372093023255 - result[1]) < EPSILON) + t.ok(Math.abs(0.9244186046511628 - result[2]) < EPSILON) + t.end() +}) + +test('transformQuat', function (t) { + var result = vec3.transformQuat([], [3, 4, 5], [6, 7, 8, 9]) + t.deepEqual(result, [882, 824, 1090]) + t.end() +})