All files / lib/basic Line.ts

87.2% Statements 109/125
95.45% Branches 42/44
71.42% Functions 10/14
87.2% Lines 109/125

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225                              1x 1x 1x             1x 1x 1x                   1x 13208x 13208x           13208x 13208x 13208x 13208x 13208x 13208x 13208x 13208x 4080x 4080x 4080x 13208x               1x                   1x                   1x                   1x 4567x 4567x 4567x 4567x 4567x 4567x 4567x 4567x 4567x 4567x 4567x 4567x 4567x               1x 53x 53x             1x 400x 400x             1x 400x 400x   1x 1923x 1923x   1x       1x 1x   6560x 1993x 1993x 1993x 1993x 1993x 6560x   6560x 6264x 6264x 6264x 6264x       6264x 6264x 6264x 6264x 6012x     1690x 1690x 6012x 6012x 6264x 6560x   1x 53x       53x 53x   53x 53x           3x     3x 3x 53x 53x   1x 907662x 898536x 898536x 898536x   907662x 22824x 952x 21872x 884838x 1681x 834x 847x 883157x 883157x 907662x   1x 8726x 8726x 1x 1x 1x  
/*
 * Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
 * http://paperjs.org/
 *
 * Copyright (c) 2011 - 2020, Jürg Lehni & Jonathan Puckey
 * http://juerglehni.com/ & https://puckey.studio/
 *
 * Distributed under the MIT license. See LICENSE file for details.
 *
 * All rights reserved.
 */
 
// TODO: remove eslint-disable comment and deal with errors over time
/* eslint-disable */
 
import { Base } from '~/straps';
import { Point } from '~/basic/Point';
import { Numerical } from '~/util/Numerical';
 
/**
 * @name Line
 * @class The Line object represents..
 * @private
 */
export const Line = Base.extend(
  /** @lends Line# */ {
    _class: 'Line',
 
    // DOCS: document Line class and constructor
    /**
     * Creates a Line object.
     *
     * @param {Point} point1
     * @param {Point} point2
     * @param {Boolean} [asVector=false]
     */
    initialize: function Line(arg0, arg1, arg2, arg3, arg4) {
      var asVector = false;
      if (arguments.length >= 4) {
        this._px = arg0;
        this._py = arg1;
        this._vx = arg2;
        this._vy = arg3;
        asVector = arg4;
      } else {
        this._px = arg0.x;
        this._py = arg0.y;
        this._vx = arg1.x;
        this._vy = arg1.y;
        asVector = arg2;
      }
      if (!asVector) {
        this._vx -= this._px;
        this._vy -= this._py;
      }
    },
 
    /**
     * The starting point of the line.
     *
     * @bean
     * @type Point
     */
    getPoint: function () {
      return new Point(this._px, this._py);
    },
 
    /**
     * The direction of the line as a vector.
     *
     * @bean
     * @type Point
     */
    getVector: function () {
      return new Point(this._vx, this._vy);
    },
 
    /**
     * The length of the line.
     *
     * @bean
     * @type Number
     */
    getLength: function () {
      return this.getVector().getLength();
    },
 
    /**
     * @param {Line} line
     * @param {Boolean} [isInfinite=false]
     * @return {Point} the intersection point of the lines, `undefined` if the
     *     two lines are collinear, or `null` if they don't intersect.
     */
    intersect: function (line, isInfinite) {
      return Line.intersect(
        this._px,
        this._py,
        this._vx,
        this._vy,
        line._px,
        line._py,
        line._vx,
        line._vy,
        true,
        isInfinite
      );
    },
 
    // DOCS: document Line#getSide(point)
    /**
     * @param {Point} point
     * @param {Boolean} [isInfinite=false]
     * @return {Number}
     */
    getSide: function (point, isInfinite) {
      return Line.getSide(this._px, this._py, this._vx, this._vy, point.x, point.y, true, isInfinite);
    },
 
    // DOCS: document Line#getDistance(point)
    /**
     * @param {Point} point
     * @return {Number}
     */
    getDistance: function (point) {
      return Math.abs(this.getSignedDistance(point));
    },
 
    // DOCS: document Line#getSignedDistance(point)
    /**
     * @param {Point} point
     * @return {Number}
     */
    getSignedDistance: function (point) {
      return Line.getSignedDistance(this._px, this._py, this._vx, this._vy, point.x, point.y, true);
    },
 
    isCollinear: function (line) {
      return Point.isCollinear(this._vx, this._vy, line._vx, line._vy);
    },
 
    isOrthogonal: function (line) {
      return Point.isOrthogonal(this._vx, this._vy, line._vx, line._vy);
    },
 
    statics: /** @lends Line */ {
      intersect: function (p1x, p1y, v1x, v1y, p2x, p2y, v2x, v2y, asVector, isInfinite) {
        // Convert 2nd points to vectors if they are not specified as such.
        if (!asVector) {
          v1x -= p1x;
          v1y -= p1y;
          v2x -= p2x;
          v2y -= p2y;
        }
        var cross = v1x * v2y - v1y * v2x;
        // Avoid divisions by 0, and errors when getting too close to 0
        if (!Numerical.isMachineZero(cross)) {
          var dx = p1x - p2x,
            dy = p1y - p2y,
            u1 = (v2x * dy - v2y * dx) / cross,
            u2 = (v1x * dy - v1y * dx) / cross,
            // Check the ranges of the u parameters if the line is not
            // allowed to extend beyond the definition points, but
            // compare with EPSILON tolerance over the [0, 1] bounds.
            epsilon = /*#=*/ Numerical.EPSILON,
            uMin = -epsilon,
            uMax = 1 + epsilon;
          if (isInfinite || (uMin < u1 && u1 < uMax && uMin < u2 && u2 < uMax)) {
            if (!isInfinite) {
              // Address the tolerance at the bounds by clipping to
              // the actual range.
              u1 = u1 <= 0 ? 0 : u1 >= 1 ? 1 : u1;
            }
            return new Point(p1x + u1 * v1x, p1y + u1 * v1y);
          }
        }
      },
 
      getSide: function (px, py, vx, vy, x, y, asVector, isInfinite) {
        if (!asVector) {
          vx -= px;
          vy -= py;
        }
        var v2x = x - px,
          v2y = y - py,
          // ccw = v2.cross(v1);
          ccw = v2x * vy - v2y * vx;
        if (!isInfinite && Numerical.isMachineZero(ccw)) {
          // If the point is on the infinite line, check if it's on the
          // finite line too: Project v2 onto v1 and determine ccw based
          // on which side of the finite line the point lies. Calculate
          // the 'u' value of the point on the line, and use it for ccw:
          // u = v2.dot(v1) / v1.dot(v1)
          ccw = (v2x * vx + v2x * vx) / (vx * vx + vy * vy);
          // If the 'u' value is within the line range, set ccw to 0,
          // otherwise its already correct sign is all we need.
          if (ccw >= 0 && ccw <= 1) ccw = 0;
        }
        return ccw < 0 ? -1 : ccw > 0 ? 1 : 0;
      },
 
      getSignedDistance: function (px, py, vx, vy, x, y, asVector) {
        if (!asVector) {
          vx -= px;
          vy -= py;
        }
        // Based on the error analysis by @iconexperience outlined in #799
        return vx === 0
          ? vy > 0
            ? x - px
            : px - x
          : vy === 0
            ? vx < 0
              ? y - py
              : py - y
            : ((x - px) * vy - (y - py) * vx) /
              (vy > vx ? vy * Math.sqrt(1 + (vx * vx) / (vy * vy)) : vx * Math.sqrt(1 + (vy * vy) / (vx * vx)));
      },
 
      getDistance: function (px, py, vx, vy, x, y, asVector) {
        return Math.abs(Line.getSignedDistance(px, py, vx, vy, x, y, asVector));
      },
    },
  }
);