All files / tools/src/utilities/math/vec2 liangBarksyClip.ts

80.48% Statements 33/41
67.64% Branches 23/34
100% Functions 2/2
80.48% Lines 33/41

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                    428x 428x 428x     9824x 9824x 4064x   5760x   5760x 2880x     2880x 1228x     2880x     2880x 2456x     5760x                       2456x 2456x 2456x 2456x   2456x 2456x 2456x               2456x                     2456x 2456x           2456x 2456x 2456x 2456x   2456x 1228x 1228x   2456x        
// Pulled from source: https://github.com/w8r/liang-barsky
// MIT Licensed.
 
/**
 * Fast, destructive implementation of Liang-Barsky line clipping algorithm.
 * It clips a 2D segment by a rectangle.
 * @author Alexander Milevski <info@w8r.name>
 * @license MIT
 */
 
const EPSILON = 1e-6;
const INSIDE = 1;
const OUTSIDE = 0;
 
function clipT(num, denom, c) {
  const [tE, tL] = c;
  if (Math.abs(denom) < EPSILON) {
    return num < 0;
  }
  const t = num / denom;
 
  if (denom > 0) {
    Iif (t > tL) {
      return 0;
    }
    if (t > tE) {
      c[0] = t;
    }
  } else {
    Iif (t < tE) {
      return 0;
    }
    if (t < tL) {
      c[1] = t;
    }
  }
  return 1;
}
 
/**
 * @param  {Point} a
 * @param  {Point} b
 * @param  {BoundingBox} box [xmin, ymin, xmax, ymax]
 * @param  {Point?} [da]
 * @param  {Point?} [db]
 * @return {number}
 */
export default function clip(a, b, box, da?, db?) {
  const [x1, y1] = a;
  const [x2, y2] = b;
  const dx = x2 - x1;
  const dy = y2 - y1;
 
  if (da === undefined || db === undefined) {
    da = a;
    db = b;
  } else E{
    da[0] = a[0];
    da[1] = a[1];
    db[0] = b[0];
    db[1] = b[1];
  }
 
  Iif (
    Math.abs(dx) < EPSILON &&
    Math.abs(dy) < EPSILON &&
    x1 >= box[0] &&
    x1 <= box[2] &&
    y1 >= box[1] &&
    y1 <= box[3]
  ) {
    return INSIDE;
  }
 
  const c = [0, 1];
  Eif (
    clipT(box[0] - x1, dx, c) &&
    clipT(x1 - box[2], -dx, c) &&
    clipT(box[1] - y1, dy, c) &&
    clipT(y1 - box[3], -dy, c)
  ) {
    const [tE, tL] = c;
    Eif (tL < 1) {
      db[0] = x1 + tL * dx;
      db[1] = y1 + tL * dy;
    }
    if (tE > 0) {
      da[0] += tE * dx;
      da[1] += tE * dy;
    }
    return INSIDE;
  }
  return OUTSIDE;
}