all files / lib/util/ Geometry.js

100% Statements 19/19
95.24% Branches 20/21
100% Functions 5/5
100% Lines 19/19
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106                  376×     370×                                     457× 168×     457× 171×     286× 286×     286×                               588× 254×     334× 295×     39×                           40×   40×                             266×          
/**
 * Computes the distance between two points
 *
 * @param  {Point}  p
 * @param  {Point}  q
 *
 * @return {Number}  distance
 */
export function pointDistance(a, b) {
  if (!a || !b) {
    return -1;
  }
 
  return Math.sqrt(
    Math.pow(a.x - b.x, 2) +
    Math.pow(a.y - b.y, 2)
  );
}
 
 
/**
 * Returns true if the point r is on the line between p and q
 *
 * @param  {Point}  p
 * @param  {Point}  q
 * @param  {Point}  r
 * @param  {Number} [accuracy=5] accuracy for points on line check (lower is better)
 *
 * @return {Boolean}
 */
export function pointsOnLine(p, q, r, accuracy) {
 
  if (typeof accuracy === 'undefined') {
    accuracy = 5;
  }
 
  if (!p || !q || !r) {
    return false;
  }
 
  var val = (q.x - p.x) * (r.y - p.y) - (q.y - p.y) * (r.x - p.x),
      dist = pointDistance(p, q);
 
  // @see http://stackoverflow.com/a/907491/412190
  return Math.abs(val / dist) <= accuracy;
}
 
 
var ALIGNED_THRESHOLD = 2;
 
/**
 * Returns whether two points are in a horizontal or vertical line.
 *
 * @param {Point} a
 * @param {Point} b
 *
 * @return {String|Boolean} returns false if the points are not
 *                          aligned or 'h|v' if they are aligned
 *                          horizontally / vertically.
 */
export function pointsAligned(a, b) {
  if (Math.abs(a.x - b.x) <= ALIGNED_THRESHOLD) {
    return 'v';
  }
 
  if (Math.abs(a.y - b.y) <= ALIGNED_THRESHOLD) {
    return 'h';
  }
 
  return false;
}
 
 
/**
 * Returns true if the point p is inside the rectangle rect
 *
 * @param  {Point}  p
 * @param  {Rect}   rect
 * @param  {Number} tolerance
 *
 * @return {Boolean}
 */
export function pointInRect(p, rect, tolerance) {
  tolerance = tolerance || 0;
 
  return p.x > rect.x - tolerance &&
         p.y > rect.y - tolerance &&
         p.x < rect.x + rect.width + tolerance &&
         p.y < rect.y + rect.height + tolerance;
}
 
/**
 * Returns a point in the middle of points p and q
 *
 * @param  {Point}  p
 * @param  {Point}  q
 *
 * @return {Point} middle point
 */
export function getMidPoint(p, q) {
  return {
    x: Math.round(p.x + ((q.x - p.x) / 2.0)),
    y: Math.round(p.y + ((q.y - p.y) / 2.0))
  };
}