{"size": 2376, "ext": "js", "max_stars_repo_path": "packages/turf-line-offset/lib/intersection.js", "max_stars_repo_name": "lhsanghcmus/turf", "max_stars_repo_stars_event_min_datetime": "2015-01-01T00:35:36.000Z", "max_stars_repo_stars_event_max_datetime": "2022-03-31T08:33:34.000Z", "max_issues_repo_path": "packages/turf-line-offset/lib/intersection.js", "max_issues_repo_name": "lhsanghcmus/turf", "max_issues_repo_issues_event_min_datetime": "2015-01-01T00:10:47.000Z", "max_issues_repo_issues_event_max_datetime": "2022-03-30T23:04:17.000Z", "max_forks_repo_path": "packages/turf-line-offset/lib/intersection.js", "max_forks_repo_name": "lhsanghcmus/turf", "max_forks_repo_forks_event_min_datetime": "2015-01-06T19:18:11.000Z", "max_forks_repo_forks_event_max_datetime": "2022-03-30T08:11:10.000Z"}
{"max_stars_count": 6394, "max_issues_count": 1814, "max_forks_count": 925, "avg_line_length": 20.4827586207, "max_line_length": 79, "alphanum_fraction": 0.6047979798}
/**
 * https://github.com/rook2pawn/node-intersection
 *
 * Author @rook2pawn
 */

/**
 * AB
 *
 * @private
 * @param {Array<Array<number>>} segment - 2 vertex line segment
 * @returns {Array<number>} coordinates [x, y]
 */
function ab(segment) {
  var start = segment[0];
  var end = segment[1];
  return [end[0] - start[0], end[1] - start[1]];
}

/**
 * Cross Product
 *
 * @private
 * @param {Array<number>} v1 coordinates [x, y]
 * @param {Array<number>} v2 coordinates [x, y]
 * @returns {Array<number>} Cross Product
 */
function crossProduct(v1, v2) {
  return v1[0] * v2[1] - v2[0] * v1[1];
}

/**
 * Add
 *
 * @private
 * @param {Array<number>} v1 coordinates [x, y]
 * @param {Array<number>} v2 coordinates [x, y]
 * @returns {Array<number>} Add
 */
function add(v1, v2) {
  return [v1[0] + v2[0], v1[1] + v2[1]];
}

/**
 * Sub
 *
 * @private
 * @param {Array<number>} v1 coordinates [x, y]
 * @param {Array<number>} v2 coordinates [x, y]
 * @returns {Array<number>} Sub
 */
function sub(v1, v2) {
  return [v1[0] - v2[0], v1[1] - v2[1]];
}

/**
 * scalarMult
 *
 * @private
 * @param {number} s scalar
 * @param {Array<number>} v coordinates [x, y]
 * @returns {Array<number>} scalarMult
 */
function scalarMult(s, v) {
  return [s * v[0], s * v[1]];
}

/**
 * Intersect Segments
 *
 * @private
 * @param {Array<number>} a coordinates [x, y]
 * @param {Array<number>} b coordinates [x, y]
 * @returns {Array<number>} intersection
 */
function intersectSegments(a, b) {
  var p = a[0];
  var r = ab(a);
  var q = b[0];
  var s = ab(b);

  var cross = crossProduct(r, s);
  var qmp = sub(q, p);
  var numerator = crossProduct(qmp, s);
  var t = numerator / cross;
  var intersection = add(p, scalarMult(t, r));
  return intersection;
}

/**
 * Is Parallel
 *
 * @private
 * @param {Array<number>} a coordinates [x, y]
 * @param {Array<number>} b coordinates [x, y]
 * @returns {boolean} true if a and b are parallel (or co-linear)
 */
function isParallel(a, b) {
  var r = ab(a);
  var s = ab(b);
  return crossProduct(r, s) === 0;
}

/**
 * Intersection
 *
 * @private
 * @param {Array<number>} a coordinates [x, y]
 * @param {Array<number>} b coordinates [x, y]
 * @returns {Array<number>|boolean} true if a and b are parallel (or co-linear)
 */
export default function intersection(a, b) {
  if (isParallel(a, b)) return false;
  return intersectSegments(a, b);
}
