diff --git a/lib/expression/docs/function/geometry/intersect.js b/lib/expression/docs/function/geometry/intersect.js new file mode 100644 index 000000000..40b10697a --- /dev/null +++ b/lib/expression/docs/function/geometry/intersect.js @@ -0,0 +1,14 @@ +module.exports = { + 'name': 'intersect', + 'category': 'Geometry', + 'syntax': [ + 'intersect(expr1, expr2, expr3, expr4)', + 'intersect(expr1, expr2, expr3)' + ], + 'description': 'Computes the intersection point of lines and/or planes.', + 'examples': [ + 'intersect([0, 0], [10, 10], [10, 0], [0, 10])', + 'intersect([1, 0, 1], [4, -2, 2], [1, 1, 1, 6])' + ], + 'seealso': [] +}; diff --git a/lib/expression/docs/index.js b/lib/expression/docs/index.js index 1f9e0b95e..f0ce36788 100644 --- a/lib/expression/docs/index.js +++ b/lib/expression/docs/index.js @@ -78,6 +78,9 @@ exports.unit = require('./function/construction/unit'); exports['eval'] = require('./function/expression/eval'); exports.help = require('./function/expression/help'); +// functions - geometry +exports.intersect = require('./function/geometry/intersect'); + // functions - logical exports['and'] = require('./function/logical/and'); exports['not'] = require('./function/logical/not'); diff --git a/lib/function/geometry/intersect.js b/lib/function/geometry/intersect.js index 8080be280..c07cd6064 100644 --- a/lib/function/geometry/intersect.js +++ b/lib/function/geometry/intersect.js @@ -33,11 +33,6 @@ module.exports = function(math) { * @return {Array} Returns the point of intersection of lines/lines-planes */ math.intersect = function intersect(w, x, y, z) { - //check for number of arguments - if (arguments.length !== 3 || arguments.length !== 4){ - throw new math.error.ArgumentsError('intersect', arguments.length, 3, 4); - } - //check for correct type and modify it accordingly if (w instanceof Matrix) { w = w.toArray(); @@ -51,7 +46,7 @@ module.exports = function(math) { else if (z instanceof Matrix) { z = z.toArray(); } - + if (!(Array.isArray(w) || Array.isArray(x) || Array.isArray(y) || Array.isArray(z))){ throw new math.error.UnsupportedTypeError('intersect', math['typeof'](w), math['typeof'](x), math['typeof'](y), math['typeof'](z)); } @@ -59,7 +54,12 @@ module.exports = function(math) { //decide which function to call based on type of arguments switch (arguments.length) { case 3: - return _intersectLinePlane(arguments[0][0], arguments[0][1], arguments[0][2], arguments[1][0], arguments[1][1], arguments[1][2], arguments[2][0], arguments[2][1], arguments[2][2], arguments[2][3]); + if(arguments[0].length === 3 && arguments[1].length === 3 && arguments[2].length === 4){ + return _intersectLinePlane(arguments[0][0], arguments[0][1], arguments[0][2], arguments[1][0], arguments[1][1], arguments[1][2], arguments[2][0], arguments[2][1], arguments[2][2], arguments[2][3]); + } + else{ + throw new TypeError('Arguments are not correct'); + } break; case 4: var is2D = (arguments[0].length === 2 && arguments[1].length === 2 && arguments[2].length === 2 && arguments[3].length === 2); @@ -73,7 +73,7 @@ module.exports = function(math) { break } default: - throw new TypeError('Arguments are not correct'); + throw new math.error.ArgumentsError('intersect', arguments.length, 3, 4); } }; @@ -84,7 +84,7 @@ module.exports = function(math) { var d4343 = (x4 - x3)*(x4 - x3) + (y4 - y3)*(y4 - y3); var d2121 = (x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1); var ta = ( d1343*d4321 - d1321*d4343 ) / ( d2121*d4343 - d4321*d4321 ); - var tb = ( d1343 + mua * d4321 ) / (d4343); + var tb = ( d1343 + ta * d4321 ) / (d4343); var pax = x1 + ta * (x2 - x1); var pay = y1 + ta * (y2 - y1); @@ -105,7 +105,7 @@ module.exports = function(math) { var d4343 = (x4 - x3)*(x4 - x3) + (y4 - y3)*(y4 - y3) + (z4 - z3)*(z4 - z3); var d2121 = (x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1) + (z2 - z1)*(z2 - z1); var ta = ( d1343*d4321 - d1321*d4343 ) / ( d2121*d4343 - d4321*d4321 ); - var tb = ( d1343 + mua * d4321 ) / (d4343); + var tb = ( d1343 + ta * d4321 ) / (d4343); var pax = x1 + ta * (x2 - x1); var pay = y1 + ta * (y2 - y1); @@ -127,5 +127,8 @@ module.exports = function(math) { var py = y1 + t * (y2 - y1); var pz = z1 + t * (z2 - z1); return [px, py, pz]; + // TODO: Add cases when line is parallel to the plane: + // (a) no intersection, + // (b) line contained in plane } } \ No newline at end of file diff --git a/lib/math.js b/lib/math.js index 4dc8e7a15..42015cb48 100644 --- a/lib/math.js +++ b/lib/math.js @@ -277,7 +277,10 @@ function create (config) { require('./function/complex/conj')(math, _config); require('./function/complex/re')(math, _config); require('./function/complex/im')(math, _config); - + + // functions - geometry + require('./function/geometry/intersect')(math, _config); + // functions - logical require('./function/logical/and')(math, _config); require('./function/logical/not')(math, _config); diff --git a/test/function/geometry/intersect.test.js b/test/function/geometry/intersect.test.js new file mode 100644 index 000000000..25f018ed4 --- /dev/null +++ b/test/function/geometry/intersect.test.js @@ -0,0 +1,35 @@ +var assert = require('assert'); +var error = require('../../../lib/error/index'); +var math = require('../../../index'); + +describe('intersect', function() { + it('should calculate the intersection point of two 2D lines', function() { + assert.deepEqual(math.intersect([0, 0], [10, 10], [10, 0], [0, 10]), [5, 5]); + }); + + it('should calculate the intersection point of two 3D lines', function() { + assert.deepEqual(math.intersect([0, 0, 0], [10, 10, 0], [10, 0, 0], [0, 10, 0]), [5, 5, 0]); + }); + + it('should calculate the intersection point of a line and a plane', function() { + assert.deepEqual(math.intersect([1, 0, 1], [4, -2, 2], [1, 1, 1, 6]), [7, -4, 3]); + }); + + it('should return null if the points do not intersect', function() { + assert.deepEqual(math.intersect([0, 1, 0], [0, 0, 0], [1, 1, 0], [1, 0, 0]), null); + assert.deepEqual(math.intersect([0, 1], [0, 0], [1, 1], [1, 0]), null); + }); + + it('should throw an error when number of arguments are other than 3 or 4', function() { + assert.throws(function () {math.intersect([2, 0, 1], [1, 1, 1, 6])}); + assert.throws(function () {math.intersect([2, 0, 1], [1, 1, 6], [2, 0, 1], [1, 1, 6], [0, 8, 1])}); + }); + + it('should throw an error for incompatible parameter types', function() { + assert.throws(function () {math.intersect(2, 3, 6)}, TypeError); + assert.throws(function () {math.intersect([2, 0, 1], [1, 1, 1], [5, 1, 10])}, /Arguments are not correct/); + assert.throws(function () {math.intersect([], [], [], [])}); + assert.throws(function () {math.intersect([2, 8, 9], 3, 6)}, TypeError); + assert.throws(function () {math.intersect(a, b, c, d)}); + }); +});