Repository: josdejong/mathjs
Pull request #458 (2015-09-04 19:44:36)

Added 3D to distance


Patch:
diff --git a/lib/function/geometry/distance.js b/lib/function/geometry/distance.js
index 4c2fc451f..1826191fb 100644
--- a/lib/function/geometry/distance.js
+++ b/lib/function/geometry/distance.js
@@ -1,38 +1,268 @@
 'use strict';
 
 function factory (type, config, load, typed) {
+  var matrix = load(require('../../type/matrix/function/matrix'));
+
   /**
-   * Calculates the Euclidean distance between two points.
-   *
-   * Syntax:
-   *
-   *    math.distance([x1, y1], [x2, y2]);
-   *    math.distance([[x1, y1], [x2, y2]);
-   *
-   * Examples:
-   *
-   *    math.distance([0,0], [4,4]) //returns 5.6569
-   *    math.distance([[0,0], [4,4]]) //returns 5.6569
-   *
-   * @param  {Array | Matrix} x   Co-ordinates of first end-point of first line
-   * @param  {Array | Matrix} y   Co-ordinates of second end-point of first line
-   * @return {Number | BigNumber} Returns the distance from two points
-   */
-
-   var distance = typed('distance', {
-    'Array, Array': function (x, y) {
-      if (!_2d(x)) { throw new TypeError('Array with 2 numbers expected for first argument'); }
-      if (!_2d(y)) { throw new TypeError('Array with 2 numbers expected for second argument'); }
-
-      return _distance2d(x[0], x[1], y[0], y[1]);
-    }
+    * Calculates:
+    *    The eucledian distance between two points in 2 and 3 dimensional spaces.
+    *    Distance between point and a line in 2 and 3 dimensional spaces.
+    *    Pairwise distance between a set of 2D or 3D points
+    * NOTE:
+    *    When substituting coefficients of a line(a, b and c), use ax + by + c = 0 instead of ax + by = c
+    *    For parametric equation of a 3D line, x0, y0, z0, a, b, c are from: (x−x0, y−y0, z−z0) = t(a, b, c)
+    *
+    * Syntax:
+    *    math.distance([x1, y1], [x2, y2])
+    *-   math.distance({pointOneX: 4, pointOneY: 5}, {pointTwoX: 2, pointTwoY: 7})
+    *    math.distance([x1, y1, z1], [x2, y2, z2])
+    *    math.distance({pointOneX: 4, pointOneY: 5, pointOneZ: 8}, {pointTwoX: 2, pointTwoY: 7, pointTwoZ: 9})
+    *    math.distance([[A], [B], [C]...])
+    *    math.distance([x1, y1], [LinePtX1, LinePtY1], [LinePtX2, LinePtY2])
+    *    math.distance({pointX: 1, pointY: 4}, {lineOnePtX: 6, lineOnePtY: 3}, {lineTwoPtX: 2, lineTwoPtY: 8})
+    *    math.distance([x1, y1, z1], [LinePtX1, LinePtY1, LinePtZ1], [LinePtX2, LinePtY2, LinePtZ2])
+    *    math.distance({pointX: 1, pointY: 4, pointZ: 7}, {lineOnePtX: 6, lineOnePtY: 3, lineOnePtZ: 4}, {lineTwoPtX: 2, lineTwoPtY: 8, lineTwoPtZ: 5})
+    *    math.distance([x1, y1], [xCoeffLine, yCoeffLine, constant])
+    *    math.distance({pointX: 10, pointY: 10}, {xCoeffLine: 8, yCoeffLine: 1, constant: 3})
+    *    math.distance([x1, y1, z1], [x0, y0, z0, a-tCoeff, b-tCoeff, c-tCoeff]) point and parametric equation of 3D line
+    *    math.distance([x, y, z], [x0, y0, z0, a, b, c])
+    *    math.distance({pointX: 2, pointY: 5, pointZ: 9}, {x0: 4, y0: 6, z0: 3, a: 4, b: 2, c: 0})
+    *
+    * Examples:
+    *    math.distance([0,0], [4,4])                     // Returns 5.6569
+    *    math.distance(
+    *     {pointOneX: 0, pointOneY: 0},
+    *     {pointTwoX: 10, pointTwoY: 10})                // Returns 14.142135623730951
+    *    math.distance([1, 0, 1], [4, -2, 2])            // Returns 3.74166
+    *    math.distance(
+    *     {pointOneX: 4, pointOneY: 5, pointOneZ: 8},
+    *     {pointTwoX: 2, pointTwoY: 7, pointTwoZ: 9})    // Returns 3
+    *    math.distance([[1, 2], [1, 2], [1, 3]])         // Returns [0, 1, 1]
+    *    math.distance([[1,2,4], [1,2,6], [8,1,3]])      // Returns [2, 7.14142842854285, 7.681145747868608]
+    *    math.distance([10, 10], [8, 1, 3])              // Returns 11.535230316796387
+    *    math.distance([10, 10], [2, 3], [-8, 0])        // Returns 8.759953130362847
+    *    math.distance(
+    *     {pointX: 1, pointY: 4},
+    *     {lineOnePtX: 6, lineOnePtY: 3},
+    *     {lineTwoPtX: 2, lineTwoPtY: 8})                // Returns 2.720549372624744
+    *    math.distance([2, 3, 1], [1, 1, 2, 5, 0, 1])    // Returns 2.3204774044612857
+    *    math.distance(
+    *     {pointX: 2, pointY: 3, pointZ: 1},
+    *     {x0: 1, y0: 1, z0: 2, a: 5, b: 0, c: 1}        // Returns 2.3204774044612857
+    *
+    * @param {Array | Matrix | Object} x    Co-ordinates of first point
+    * @param {Array | Matrix | Object} y    Co-ordinates of second point
+    * @return {Number | BigNumber} Returns the distance from two/three points
+  */
+
+  var distance = typed('distance', {
+    'Array, Array, Array': function(x, y, z){
+      // Point to Line 2D; (x=Point, y=LinePoint1, z=LinePoint2)
+      if (x.length == 2 && y.length == 2 && z.length == 2){
+        if (!_2d(x)) { throw new TypeError('Array with 2 numbers expected for first argument'); }
+        if (!_2d(y)) { throw new TypeError('Array with 2 numbers expected for second argument'); }
+        if (!_2d(z)) { throw new TypeError('Array with 2 numbers expected for third argument'); }
+        var m = (z[1]-z[0])/(y[1]-y[0]);
+        var xCoeff = m*m*y[0];
+        var yCoeff = -1*(m*y[0]);
+        var constant = x[1];
+
+        return _distancePointLine2D(x[0], x[1], xCoeff, yCoeff, constant);
+      }
+      else{
+        throw new TypeError('Invalid Arguments: Try again');
+      }
+    },
+    'Object, Object, Object': function(x, y, z){
+      if (Object.keys(x).length == 2 && Object.keys(y).length == 2 && Object.keys(z).length == 2){
+        if (!_2d(x)) { throw new TypeError('Values of pointX and pointY should be numbers'); }
+        if (!_2d(y)) { throw new TypeError('Values of lineOnePtX and lineOnePtY should be numbers'); }
+        if (!_2d(z)) { throw new TypeError('Values of lineTwoPtX and lineTwoPtY should be numbers'); }
+        if (x.hasOwnProperty('pointX') && x.hasOwnProperty('pointY') && y.hasOwnProperty('lineOnePtX') &&
+          y.hasOwnProperty('lineOnePtY') && z.hasOwnProperty('lineTwoPtX') && z.hasOwnProperty('lineTwoPtY')){
+          var m = (z.lineTwoPtY-z.lineTwoPtX)/(y.lineOnePtY-y.lineOnePtX);
+          var xCoeff = m*m*y.lineOnePtX;
+          var yCoeff = -1*(m*y.lineOnePtX);
+          var constant = x.pointX;
+
+          return _distancePointLine2D(x.pointX, x.pointY, xCoeff, yCoeff, constant);
+        }
+        else{
+          throw new TypeError('Key names do not match');
+        }
+      }
+      else{
+        throw new TypeError('Invalid Arguments: Try again');
+      }
+    },
+    'Array, Array': function(x, y){
+      // Point to Line 2D; (x=[pointX, pointY], y=[x-coeff, y-coeff, const])
+      if (x.length == 2 && y.length == 3){
+        if (!_2d(x)) { throw new TypeError('Array with 2 numbers expected for first argument'); }
+        if (!_3d(y)) { throw new TypeError('Array with 3 numbers expected for second argument'); }
+
+        return _distancePointLine2D(x[0], x[1], y[0], y[1], y[2]);
+      }
+      // Point to Line 3D
+      else if (x.length == 3 && y.length == 6){
+        if (!_3d(x)) { throw new TypeError('Array with 3 numbers expected for first argument'); }
+        if (!_parametricLine(y)) { throw new TypeError('Array with 6 numbers expected for second argument'); }
+
+        return _distancePointLine3D(x[0], x[1], x[2], y[0], y[1], y[2], y[3], y[4], y[5]);
+      }
+      // Point to Point 2D
+      else if (x.length == 2 && y.length == 2){
+        if (!_2d(x)) { throw new TypeError('Array with 2 numbers expected for first argument'); }
+        if (!_2d(y)) { throw new TypeError('Array with 2 numbers expected for second argument'); }
+
+        return _distance2d(x[0], x[1], y[0], y[1]);
+      }
+      // Point to Point 3D
+      else if(x.length == 3 && y.length == 3){
+        if (!_3d(x)) { throw new TypeError('Array with 3 numbers expected for first argument'); }
+        if (!_3d(y)) { throw new TypeError('Array with 3 numbers expected for second argument'); }
+
+        return _distance3d(x[0], x[1], x[2], y[0], y[1], y[2]);
+      }
+      else{
+        throw new TypeError('Invalid Arguments: Try again');
+      }
+    },
+    'Object, Object': function(x, y){
+      if (Object.keys(x).length == 2 && Object.keys(y).length == 3){
+        if (!_2d(x)) { throw new TypeError('Values of pointX and pointY should be numbers'); }
+        if (!_3d(y)) { throw new TypeError('Values of xCoeffLine, yCoeffLine and constant should be numbers'); }
+        if (x.hasOwnProperty('pointX') && x.hasOwnProperty('pointY') && y.hasOwnProperty('xCoeffLine') &&
+          y.hasOwnProperty('yCoeffLine') && y.hasOwnProperty('yCoeffLine')){
+
+          return _distancePointLine2D(x.pointX, x.pointY, y.xCoeffLine, y.yCoeffLine, y.constant);
+        }
+        else{
+          throw new TypeError('Key names do not match');
+        }
+      }
+      // Point to Line 3D
+      else if (Object.keys(x).length == 3 && Object.keys(y).length == 6){
+        if (!_3d(x)) { throw new TypeError('Values of pointX, pointY and pointZ should be numbers'); }
+        if (!_parametricLine(y)) { throw new TypeError('Values of x0, y0, z0, a, b and c should be numbers'); }
+        if (x.hasOwnProperty('pointX') && x.hasOwnProperty('pointY') && y.hasOwnProperty('x0') &&
+          y.hasOwnProperty('y0') && y.hasOwnProperty('z0') && y.hasOwnProperty('a') &&
+          y.hasOwnProperty('b') && y.hasOwnProperty('c')){
+
+          return _distancePointLine3D(x.pointX, x.pointY, x.pointZ, y.x0, y.y0, y.z0, y.a, y.b, y.c);
+        }
+        else{
+          throw new TypeError('Key names do not match');
+        }
+      }
+      // Point to Point 2D
+      else if (Object.keys(x).length == 2 && Object.keys(y).length == 2){
+        if (!_2d(x)) { throw new TypeError('Values of pointOneX and pointOneY should be numbers'); }
+        if (!_2d(y)) { throw new TypeError('Values of pointTwoX and pointTwoY should be numbers'); }
+        if (x.hasOwnProperty('pointOneX') && x.hasOwnProperty('pointOneY') &&
+          y.hasOwnProperty('pointTwoX') && y.hasOwnProperty('pointTwoY')){
 
+          return _distance2d(x.pointOneX, x.pointOneY, y.pointTwoX, y.pointTwoY);
+        }
+        else{
+          throw new TypeError('Key names do not match');
+        }
+      }
+      // Point to Point 3D
+      else if(Object.keys(x).length == 3 && Object.keys(y).length == 3){
+        if (!_3d(x)) { throw new TypeError('Values of pointOneX, pointOneY and pointOneZ should be numbers'); }
+        if (!_3d(y)) { throw new TypeError('Values of pointTwoX, pointTwoY and pointTwoZ should be numbers'); }
+        if (x.hasOwnProperty('pointOneX') && x.hasOwnProperty('pointOneY') && x.hasOwnProperty('pointOneZ') &&
+          y.hasOwnProperty('pointTwoX') && y.hasOwnProperty('pointTwoY') && y.hasOwnProperty('pointTwoZ')){
+
+          return _distance3d(x.pointOneX, x.pointOneY, x.pointOneZ, y.pointTwoX, y.pointTwoY, y.pointTwoZ);
+        }
+        else {
+          throw new TypeError('Key names do not match');
+        }
+      }
+      else{
+        throw new TypeError('Invalid Arguments: Try again');
+      }
+    },
+    'Array': function(arr){
+      if (!_pairwise(arr)) { throw new TypeError('Incorrect array format entered for pairwise distance calculation'); }
+
+      return _distancePairwise(arr);
+    }
   });
-   return distance;
- }
+  return distance;
+}
+
+function _2d(a){
+  // checks if the number of arguments are correct in count and are valid (should be numbers)
+  if (a.constructor !== Array){
+    a = _objectToArray(a);
+  }
+  return typeof a[0] === 'number' && typeof a[1] === 'number';
+}
 
- function _2d(x) {
-  return x.length === 2 && typeof x[0] === 'number' && typeof x[1] === 'number';
+function _3d(a){
+  // checks if the number of arguments are correct in count and are valid (should be numbers)
+  if (a.constructor !== Array){
+    a = _objectToArray(a);
+  }
+  return typeof a[0] === 'number' && typeof a[1] === 'number' && typeof a[2] === 'number';
+}
+
+function _parametricLine(a){
+  if (a.constructor !== Array){
+    a = _objectToArray(a);
+  }
+  return typeof a[0] === 'number' && typeof a[1] === 'number' && typeof a[2] === 'number' &&
+    typeof a[3] === 'number' && typeof a[4] === 'number' && typeof a[5] === 'number';
+
+}
+
+function _objectToArray(o){
+  var keys = Object.keys(o);
+  var a = [];
+  for (var i = 0; i < keys.length; i++) {
+    a.push(o[keys[i]]);
+  }
+  return a;
+}
+
+function _pairwise(a){
+  //checks for valid arguments passed to _distancePairwise(Array)
+  if (a[0].length == 2 && typeof a[0][0] === 'number' && typeof a[0][1] === 'number'){
+    for(var i in a){
+      if (a[i].length != 2 || typeof a[i][0] !== 'number' || typeof a[i][1] !== 'number'){
+        return false;
+      }
+    }
+  }
+  else if (a[0].length == 3 && typeof a[0][0] === 'number' && typeof a[0][1] === 'number' && typeof a[0][2] === 'number'){
+    for(var i in a){
+      if (a[i].length != 3 || typeof a[i][0] !== 'number' || typeof a[i][1] !== 'number' || typeof a[i][2] !== 'number'){
+        return false;
+      }
+    }
+  }
+  else{
+    return false;
+  }
+  return true;
+}
+
+function _distancePointLine2D(x, y, a, b, c){
+  var num =  Math.abs(a*x + b*y + c);
+  var den = Math.pow((a*a + b*b), 0.5);
+  var result = (num/den);
+  return result;
+}
+
+function _distancePointLine3D(x, y, z, x0, y0, z0, a, b, c){
+  var num = [((y0-y)*(c))-((z0-z)*(b)), ((z0-z)*(a))-((x0-x)*(c)), ((x0-x)*(b))-((y0-y)*(a))]
+  num = Math.pow(num[0]*num[0] + num[1]*num[1] + num[2]*num[2], 0.5);
+  var den = Math.pow(a*a + b*b + c*c, 0.5);
+  var result = num/den;
+  return result;
 }
 
 function _distance2d(x1, y1, x2, y2){
@@ -43,6 +273,29 @@ function _distance2d(x1, y1, x2, y2){
   return result;
 }
 
+function _distance3d(x1, y1, z1, x2, y2, z2){
+  var zDiff = z2 - z1;
+  var yDiff = y2 - y1;
+  var xDiff = x2 - x1;
+  var radicant = zDiff * zDiff + yDiff * yDiff + xDiff * xDiff;
+  var result = Math.pow(radicant, 0.5);
+  return result;
+}
+
+function _distancePairwise(a){
+  var result = [];
+  for(var i = 0; i < a.length-1; i++){
+    for(var j = i+1; j < a.length; j++){
+      if (a[0].length == 2){
+        result.push(_distance2d(a[i][0], a[i][1], a[j][0], a[j][1]));
+      }
+      else if (a[0].length == 3){
+        result.push(_distance3d(a[i][0], a[i][1], a[i][2], a[j][0], a[j][1], a[j][2]));
+      }
+    }
+  }
+  return result;
+}
 
 exports.name = 'distance';
 exports.factory = factory;


Test patch:
diff --git a/test/function/geometry/distance.test.js b/test/function/geometry/distance.test.js
index b34afd7d0..e4be63687 100644
--- a/test/function/geometry/distance.test.js
+++ b/test/function/geometry/distance.test.js
@@ -1,27 +1,92 @@
 var assert = require('assert');
 var error = require('../../../lib/error/index');
 var math = require('../../../index');
+
 describe('distance', function() {
   it('should calculate the distance of two 2D points', function() {
     assert.equal(math.distance([0, 0], [10, 10]), 14.142135623730951);
     assert.equal(math.distance(math.matrix([0,0]),math.matrix([10,10])), 14.142135623730951);
+    assert.equal(math.distance(math.matrix([0,0,0]),math.matrix([10,10,0])), 14.142135623730951);
+    assert.equal(math.distance({pointOneX: 0, pointOneY: 0}, {pointTwoX: 10, pointTwoY: 10}), 14.142135623730951);
+  });
+
+  it('should calculate distance between two 3d points', function(){
+    assert.equal(math.distance([4, 5, 8], [2, 7, 9]), 3);
+    assert.equal(math.distance(math.matrix([0, 0, 0]), math.matrix([10, 10, 0])), 14.142135623730951);
+    assert.equal(math.distance(math.matrix([0.31, 0.2, -0.21]), [0.4234, -0.212, -0.2342]), 0.42800607472324503);
+    assert.equal(math.distance([67435, 654667, 3545567], [53467, 34567, 654356]), 2956995.1236931384);
+    assert.equal(math.distance([-21, -230, -2141], math.matrix([-1234, -3122, -1242])), 3262.396971553278);
+    assert.equal(math.distance({pointOneX: 4, pointOneY: 5, pointOneZ: 8}, {pointTwoX: 2, pointTwoY: 7, pointTwoZ: 9}), 3);
+  });
+
+  it('should calculate distance for inputs passed as objects', function(){
+    assert.deepEqual(math.distance({pointX: 1, pointY: 4}, {lineOnePtX: 6, lineOnePtY: 3}, {lineTwoPtX: 2, lineTwoPtY: 8}), 2.720549372624744);
+    assert.deepEqual(math.distance({pointX: 10, pointY: 10}, {xCoeffLine: 8, yCoeffLine: 1, constant: 3}), 11.535230316796387);
+    assert.equal(math.distance({pointOneX: 0, pointOneY: 0}, {pointTwoX: 10, pointTwoY: 10}), 14.142135623730951);
+    assert.throws(function() {math.distance({pointX: 1, pointY: 4}, {lineOnePtX: 'l', lineOnePtY: 3}, {lineTwoPtX: 2, lineTwoPtY: 8})}, TypeError);
+    assert.equal(math.distance({pointOneX: 4, pointOneY: 5, pointOneZ: 8}, {pointTwoX: 2, pointTwoY: 7, pointTwoZ: 9}), 3);
   });
 
-  it('should calculate distance for non-zero values', function() {
+  it('should calculate distance for all non-zero values', function() {
     assert.equal(math.distance([1, 1], [10,10]), 12.727922061357855);
     assert.equal(math.distance([-1, -1], [10,10]), 15.556349186104045);
-    assert.equal(math.distance([-1, 8], [5,10]), 6.324555320336759);
+    assert.equal(math.distance(math.matrix([-1, 8]), [5,10]), 6.324555320336759);
     assert.equal(math.distance([-100, 60], [0,500]), 451.22056690713913);
     assert.equal(math.distance([-100.78, 60.04], [0.3,500.09]), 451.5098768576386);
+    assert.equal(math.distance([74, -34, -0.5], math.matrix([34, 100, -4.33])), 139.89520685141431);
+    assert.deepEqual(math.distance([1, -1, -1], [2, 2, 0.1, 1, 2, 2]), 1.3437096247164249);
   });
 
   it('should throw an error for incompatible parameter types', function() {
     assert.throws(function() {math.distance(0.5)}, TypeError);
     assert.throws(function() {math.distance('1')}, TypeError);
+    assert.throws(function() {math.distance(["abc", "def"], [1, 3])}, TypeError);
+    assert.throws(function() {math.distance(['2', '3'], math.matrix(["a", "c"]), [1, -0.445364786543434])}, TypeError);
+    assert.throws(function() {math.distance({pointX: 1, pointY: 4}, {lineOnePtX: 'l', lineOnePtY: 3}, {lineTwoPtX: 2, lineTwoPtY: 8})}, TypeError);
+    assert.throws(function() {math.distance({wrongkeyname: 2, english: 3, pointZ: 1}, {x0: 1, y0: 1, z0: 2, a: 5, b: 0, c: 1})}, TypeError);
+  });
+
+  it('should throw an error for unsupported number of parameters', function() {
+    assert.throws(function() {math.distance([0, 0])}, TypeError);
+    assert.throws(function() {math.distance([9, 4, 3.6])}, TypeError);
+    assert.throws(function() {math.distance([[1, 2, 4],math.matrix([1, 2]),[8, 1, 3]])}, TypeError);
+    assert.throws(function() {math.distance([-0.5, 4.3],[3.2, -4.654323, 3.3, 6.5, 3.4])}, TypeError);
+  });
+
+  it('should calculate pairwise distance between more than two 2D points accurately', function(){
+    assert.deepEqual(math.distance([[1,2],[1,2],[1,3]]), [0, 1, 1]);
+    assert.deepEqual(math.distance([[0,2],[-2,0],[0,2]]), [ 2.8284271247461903, 0, 2.8284271247461903 ]);
+    assert.deepEqual(math.distance([[1,2], [2,3], [2,4], [3,0]]),
+      [1.4142135623730951,2.23606797749979,2.8284271247461903,1,3.1622776601683795,4.123105625617661]);
+  });
+
+  it('should calculate pairwise distance between more than two 3D points accurately', function(){
+    assert.deepEqual(math.distance([[0,0,0],[1,0,0],[0,1,0],[0,0,1]]), [1,1,1,1.4142135623730951,1.4142135623730951,1.4142135623730951]);
+    assert.deepEqual(math.distance([[1,2,4],[1,2,6],[8,1,3]]), [2, 7.14142842854285, 7.681145747868608]);
+    assert.deepEqual(math.distance([[-41,52,24],[61,-28,60],[-38,11,53]]), [134.5362404707371, 50.309044912421065, 106.63489110042735]);
+    assert.deepEqual(math.distance([[3.1,5.2,4.5],[4.1,0.2,6.4],[-5.8,-4.1,3021]]), [5.441507144165116,3016.527465480797,3014.6193225679426]);
+  });
+
+  it('should calculate distance between a point and a line segment given by an equation in 2D accurately', function(){
+    assert.deepEqual(math.distance([0.1123, -0.242], [0.1316, -0.2421, 0.122135]), 0.7094821347343443);
+    assert.deepEqual(math.distance([10, 10], [8, 1, 3]), 11.535230316796387);
+    assert.deepEqual(math.distance([12.5, -0.5], [8.5, -1, 3.75]), 12.91095785619739);
+    assert.deepEqual(math.distance([-34510, -1032], [8996, -10599, 34653]), 21542.094604263482);
+    assert.deepEqual(math.distance({pointX: 10, pointY: 10}, {xCoeffLine: 8, yCoeffLine: 1, constant: 3}), 11.535230316796387);
+  });
+
+  it('should calculate distance between a point and a line segment given by two points in 2D accurately', function(){
+    assert.deepEqual(math.distance(math.matrix([10, 10]), math.matrix([2, 3]), math.matrix([-8, 0])), 8.759953130362847);
+    assert.deepEqual(math.distance([0.23, -0.1240], [-0.232, 13.292], [-0.34, 0.346]), 10.658908662088363);
+    assert.deepEqual(math.distance([-10, 0.54], [38, 12.8], [94.33, -239]), 10.012171799590002);
+    assert.deepEqual(math.distance({pointX: 1, pointY: 4}, {lineOnePtX: 6, lineOnePtY: 3}, {lineTwoPtX: 2, lineTwoPtY: 8}), 2.720549372624744);
   });
 
-  it('should throw an error for different number of parameters', function() {
-    assert.throws(function() {math.distance([0,0])}, TypeError);
-    assert.throws(function() {math.distance([0,0],[0,0],[0,0])}, TypeError);
+  it('should calculate distance between point and line segment(with parametric co-ordinates) in 3D accurately', function(){
+    assert.deepEqual(math.distance([2, 3, 1], [1, 1, 2, 5, 0, 1]), 2.3204774044612857);
+    assert.deepEqual(math.distance(math.matrix([1, -1, -1]), math.matrix([2, 2, 0, 1, 2, 2])), 1.414213562373095);
+    assert.deepEqual(math.distance([-341, 12, 84.34], [-3.2, 212, 1.240, -51241, 22.2, -4652]), 229.9871046141146);
+    assert.deepEqual(math.distance({pointX: 2, pointY: 3, pointZ: 1}, {x0: 1, y0: 1, z0: 2, a: 5, b: 0, c: 1}), 2.3204774044612857);
   });
-});
\ No newline at end of file
+
+});