mirror of
				https://github.com/excalidraw/excalidraw.git
				synced 2025-11-04 04:44:31 +01:00 
			
		
		
		
	chore: Refactor doBoundsIntersect (#9657)
This commit is contained in:
		@@ -24,7 +24,6 @@ import {
 | 
			
		||||
  pointsEqual,
 | 
			
		||||
  lineSegmentIntersectionPoints,
 | 
			
		||||
  PRECISION,
 | 
			
		||||
  doBoundsIntersect,
 | 
			
		||||
} from "@excalidraw/math";
 | 
			
		||||
 | 
			
		||||
import type { LocalPoint, Radians } from "@excalidraw/math";
 | 
			
		||||
@@ -33,7 +32,11 @@ import type { AppState } from "@excalidraw/excalidraw/types";
 | 
			
		||||
 | 
			
		||||
import type { MapEntry, Mutable } from "@excalidraw/common/utility-types";
 | 
			
		||||
 | 
			
		||||
import { getCenterForBounds, getElementBounds } from "./bounds";
 | 
			
		||||
import {
 | 
			
		||||
  doBoundsIntersect,
 | 
			
		||||
  getCenterForBounds,
 | 
			
		||||
  getElementBounds,
 | 
			
		||||
} from "./bounds";
 | 
			
		||||
import { intersectElementWithLineSegment } from "./collision";
 | 
			
		||||
import { distanceToElement } from "./distance";
 | 
			
		||||
import {
 | 
			
		||||
 
 | 
			
		||||
@@ -584,7 +584,7 @@ const solveQuadratic = (
 | 
			
		||||
  return [s1, s2];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const getCubicBezierCurveBound = (
 | 
			
		||||
export const getCubicBezierCurveBound = (
 | 
			
		||||
  p0: GlobalPoint,
 | 
			
		||||
  p1: GlobalPoint,
 | 
			
		||||
  p2: GlobalPoint,
 | 
			
		||||
@@ -1230,6 +1230,20 @@ export const pointInsideBounds = <P extends GlobalPoint | LocalPoint>(
 | 
			
		||||
): boolean =>
 | 
			
		||||
  p[0] > bounds[0] && p[0] < bounds[2] && p[1] > bounds[1] && p[1] < bounds[3];
 | 
			
		||||
 | 
			
		||||
export const doBoundsIntersect = (
 | 
			
		||||
  bounds1: Bounds | null,
 | 
			
		||||
  bounds2: Bounds | null,
 | 
			
		||||
): boolean => {
 | 
			
		||||
  if (bounds1 == null || bounds2 == null) {
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const [minX1, minY1, maxX1, maxY1] = bounds1;
 | 
			
		||||
  const [minX2, minY2, maxX2, maxY2] = bounds2;
 | 
			
		||||
 | 
			
		||||
  return minX1 < maxX2 && maxX1 > minX2 && minY1 < maxY2 && maxY1 > minY2;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const elementCenterPoint = (
 | 
			
		||||
  element: ExcalidrawElement,
 | 
			
		||||
  elementsMap: ElementsMap,
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,6 @@ import {
 | 
			
		||||
  vectorFromPoint,
 | 
			
		||||
  vectorNormalize,
 | 
			
		||||
  vectorScale,
 | 
			
		||||
  doBoundsIntersect,
 | 
			
		||||
} from "@excalidraw/math";
 | 
			
		||||
 | 
			
		||||
import {
 | 
			
		||||
@@ -19,15 +18,22 @@ import {
 | 
			
		||||
  ellipseSegmentInterceptPoints,
 | 
			
		||||
} from "@excalidraw/math/ellipse";
 | 
			
		||||
 | 
			
		||||
import type { GlobalPoint, LineSegment, Radians } from "@excalidraw/math";
 | 
			
		||||
import type {
 | 
			
		||||
  Curve,
 | 
			
		||||
  GlobalPoint,
 | 
			
		||||
  LineSegment,
 | 
			
		||||
  Radians,
 | 
			
		||||
} from "@excalidraw/math";
 | 
			
		||||
 | 
			
		||||
import type { FrameNameBounds } from "@excalidraw/excalidraw/types";
 | 
			
		||||
 | 
			
		||||
import { isPathALoop } from "./utils";
 | 
			
		||||
import {
 | 
			
		||||
  type Bounds,
 | 
			
		||||
  doBoundsIntersect,
 | 
			
		||||
  elementCenterPoint,
 | 
			
		||||
  getCenterForBounds,
 | 
			
		||||
  getCubicBezierCurveBound,
 | 
			
		||||
  getElementBounds,
 | 
			
		||||
} from "./bounds";
 | 
			
		||||
import {
 | 
			
		||||
@@ -255,13 +261,75 @@ export const intersectElementWithLineSegment = (
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const curveIntersections = (
 | 
			
		||||
  curves: Curve<GlobalPoint>[],
 | 
			
		||||
  segment: LineSegment<GlobalPoint>,
 | 
			
		||||
  intersections: GlobalPoint[],
 | 
			
		||||
  center: GlobalPoint,
 | 
			
		||||
  angle: Radians,
 | 
			
		||||
  onlyFirst = false,
 | 
			
		||||
) => {
 | 
			
		||||
  for (const c of curves) {
 | 
			
		||||
    // Optimize by doing a cheap bounding box check first
 | 
			
		||||
    const b1 = getCubicBezierCurveBound(c[0], c[1], c[2], c[3]);
 | 
			
		||||
    const b2 = [
 | 
			
		||||
      Math.min(segment[0][0], segment[1][0]),
 | 
			
		||||
      Math.min(segment[0][1], segment[1][1]),
 | 
			
		||||
      Math.max(segment[0][0], segment[1][0]),
 | 
			
		||||
      Math.max(segment[0][1], segment[1][1]),
 | 
			
		||||
    ] as Bounds;
 | 
			
		||||
 | 
			
		||||
    if (!doBoundsIntersect(b1, b2)) {
 | 
			
		||||
      continue;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const hits = curveIntersectLineSegment(c, segment);
 | 
			
		||||
 | 
			
		||||
    if (hits.length > 0) {
 | 
			
		||||
      for (const j of hits) {
 | 
			
		||||
        intersections.push(pointRotateRads(j, center, angle));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (onlyFirst) {
 | 
			
		||||
        return intersections;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return intersections;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const lineIntersections = (
 | 
			
		||||
  lines: LineSegment<GlobalPoint>[],
 | 
			
		||||
  segment: LineSegment<GlobalPoint>,
 | 
			
		||||
  intersections: GlobalPoint[],
 | 
			
		||||
  center: GlobalPoint,
 | 
			
		||||
  angle: Radians,
 | 
			
		||||
  onlyFirst = false,
 | 
			
		||||
) => {
 | 
			
		||||
  for (const l of lines) {
 | 
			
		||||
    const intersection = lineSegmentIntersectionPoints(l, segment);
 | 
			
		||||
    if (intersection) {
 | 
			
		||||
      intersections.push(pointRotateRads(intersection, center, angle));
 | 
			
		||||
 | 
			
		||||
      if (onlyFirst) {
 | 
			
		||||
        return intersections;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return intersections;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const intersectLinearOrFreeDrawWithLineSegment = (
 | 
			
		||||
  element: ExcalidrawLinearElement | ExcalidrawFreeDrawElement,
 | 
			
		||||
  segment: LineSegment<GlobalPoint>,
 | 
			
		||||
  onlyFirst = false,
 | 
			
		||||
): GlobalPoint[] => {
 | 
			
		||||
  // NOTE: This is the only one which return the decomposed elements
 | 
			
		||||
  // rotated! This is due to taking advantage of roughjs definitions.
 | 
			
		||||
  const [lines, curves] = deconstructLinearOrFreeDrawElement(element);
 | 
			
		||||
  const intersections = [];
 | 
			
		||||
  const intersections: GlobalPoint[] = [];
 | 
			
		||||
 | 
			
		||||
  for (const l of lines) {
 | 
			
		||||
    const intersection = lineSegmentIntersectionPoints(l, segment);
 | 
			
		||||
@@ -275,6 +343,19 @@ const intersectLinearOrFreeDrawWithLineSegment = (
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for (const c of curves) {
 | 
			
		||||
    // Optimize by doing a cheap bounding box check first
 | 
			
		||||
    const b1 = getCubicBezierCurveBound(c[0], c[1], c[2], c[3]);
 | 
			
		||||
    const b2 = [
 | 
			
		||||
      Math.min(segment[0][0], segment[1][0]),
 | 
			
		||||
      Math.min(segment[0][1], segment[1][1]),
 | 
			
		||||
      Math.max(segment[0][0], segment[1][0]),
 | 
			
		||||
      Math.max(segment[0][1], segment[1][1]),
 | 
			
		||||
    ] as Bounds;
 | 
			
		||||
 | 
			
		||||
    if (!doBoundsIntersect(b1, b2)) {
 | 
			
		||||
      continue;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const hits = curveIntersectLineSegment(c, segment);
 | 
			
		||||
 | 
			
		||||
    if (hits.length > 0) {
 | 
			
		||||
@@ -292,7 +373,7 @@ const intersectLinearOrFreeDrawWithLineSegment = (
 | 
			
		||||
const intersectRectanguloidWithLineSegment = (
 | 
			
		||||
  element: ExcalidrawRectanguloidElement,
 | 
			
		||||
  elementsMap: ElementsMap,
 | 
			
		||||
  l: LineSegment<GlobalPoint>,
 | 
			
		||||
  segment: LineSegment<GlobalPoint>,
 | 
			
		||||
  offset: number = 0,
 | 
			
		||||
  onlyFirst = false,
 | 
			
		||||
): GlobalPoint[] => {
 | 
			
		||||
@@ -300,48 +381,43 @@ const intersectRectanguloidWithLineSegment = (
 | 
			
		||||
  // To emulate a rotated rectangle we rotate the point in the inverse angle
 | 
			
		||||
  // instead. It's all the same distance-wise.
 | 
			
		||||
  const rotatedA = pointRotateRads<GlobalPoint>(
 | 
			
		||||
    l[0],
 | 
			
		||||
    segment[0],
 | 
			
		||||
    center,
 | 
			
		||||
    -element.angle as Radians,
 | 
			
		||||
  );
 | 
			
		||||
  const rotatedB = pointRotateRads<GlobalPoint>(
 | 
			
		||||
    l[1],
 | 
			
		||||
    segment[1],
 | 
			
		||||
    center,
 | 
			
		||||
    -element.angle as Radians,
 | 
			
		||||
  );
 | 
			
		||||
  const rotatedIntersector = lineSegment(rotatedA, rotatedB);
 | 
			
		||||
 | 
			
		||||
  // Get the element's building components we can test against
 | 
			
		||||
  const [sides, corners] = deconstructRectanguloidElement(element, offset);
 | 
			
		||||
 | 
			
		||||
  const intersections: GlobalPoint[] = [];
 | 
			
		||||
 | 
			
		||||
  for (const s of sides) {
 | 
			
		||||
    const intersection = lineSegmentIntersectionPoints(
 | 
			
		||||
      lineSegment(rotatedA, rotatedB),
 | 
			
		||||
      s,
 | 
			
		||||
    );
 | 
			
		||||
    if (intersection) {
 | 
			
		||||
      intersections.push(pointRotateRads(intersection, center, element.angle));
 | 
			
		||||
  lineIntersections(
 | 
			
		||||
    sides,
 | 
			
		||||
    rotatedIntersector,
 | 
			
		||||
    intersections,
 | 
			
		||||
    center,
 | 
			
		||||
    element.angle,
 | 
			
		||||
    onlyFirst,
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
      if (onlyFirst) {
 | 
			
		||||
        return intersections;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  if (onlyFirst && intersections.length > 0) {
 | 
			
		||||
    return intersections;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for (const t of corners) {
 | 
			
		||||
    const hits = curveIntersectLineSegment(t, lineSegment(rotatedA, rotatedB));
 | 
			
		||||
 | 
			
		||||
    if (hits.length > 0) {
 | 
			
		||||
      for (const j of hits) {
 | 
			
		||||
        intersections.push(pointRotateRads(j, center, element.angle));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (onlyFirst) {
 | 
			
		||||
        return intersections;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  curveIntersections(
 | 
			
		||||
    corners,
 | 
			
		||||
    rotatedIntersector,
 | 
			
		||||
    intersections,
 | 
			
		||||
    center,
 | 
			
		||||
    element.angle,
 | 
			
		||||
    onlyFirst,
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  return intersections;
 | 
			
		||||
};
 | 
			
		||||
@@ -366,38 +442,32 @@ const intersectDiamondWithLineSegment = (
 | 
			
		||||
  // points. It's all the same distance-wise.
 | 
			
		||||
  const rotatedA = pointRotateRads(l[0], center, -element.angle as Radians);
 | 
			
		||||
  const rotatedB = pointRotateRads(l[1], center, -element.angle as Radians);
 | 
			
		||||
  const rotatedIntersector = lineSegment(rotatedA, rotatedB);
 | 
			
		||||
 | 
			
		||||
  const [sides, corners] = deconstructDiamondElement(element, offset);
 | 
			
		||||
 | 
			
		||||
  const intersections: GlobalPoint[] = [];
 | 
			
		||||
 | 
			
		||||
  for (const s of sides) {
 | 
			
		||||
    const intersection = lineSegmentIntersectionPoints(
 | 
			
		||||
      lineSegment(rotatedA, rotatedB),
 | 
			
		||||
      s,
 | 
			
		||||
    );
 | 
			
		||||
    if (intersection) {
 | 
			
		||||
      intersections.push(pointRotateRads(intersection, center, element.angle));
 | 
			
		||||
  lineIntersections(
 | 
			
		||||
    sides,
 | 
			
		||||
    rotatedIntersector,
 | 
			
		||||
    intersections,
 | 
			
		||||
    center,
 | 
			
		||||
    element.angle,
 | 
			
		||||
    onlyFirst,
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
      if (onlyFirst) {
 | 
			
		||||
        return intersections;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  if (onlyFirst && intersections.length > 0) {
 | 
			
		||||
    return intersections;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for (const t of corners) {
 | 
			
		||||
    const hits = curveIntersectLineSegment(t, lineSegment(rotatedA, rotatedB));
 | 
			
		||||
 | 
			
		||||
    if (hits.length > 0) {
 | 
			
		||||
      for (const j of hits) {
 | 
			
		||||
        intersections.push(pointRotateRads(j, center, element.angle));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (onlyFirst) {
 | 
			
		||||
        return intersections;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  curveIntersections(
 | 
			
		||||
    corners,
 | 
			
		||||
    rotatedIntersector,
 | 
			
		||||
    intersections,
 | 
			
		||||
    center,
 | 
			
		||||
    element.angle,
 | 
			
		||||
    onlyFirst,
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  return intersections;
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -90,6 +90,12 @@ const setElementShapesCacheEntry = <T extends ExcalidrawElement>(
 | 
			
		||||
  shapes.set(offset, shape);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Returns the **rotated** components of freedraw, line or arrow elements.
 | 
			
		||||
 *
 | 
			
		||||
 * @param element The linear element to deconstruct
 | 
			
		||||
 * @returns The rotated in components.
 | 
			
		||||
 */
 | 
			
		||||
export function deconstructLinearOrFreeDrawElement(
 | 
			
		||||
  element: ExcalidrawLinearElement | ExcalidrawFreeDrawElement,
 | 
			
		||||
): [LineSegment<GlobalPoint>[], Curve<GlobalPoint>[]] {
 | 
			
		||||
@@ -171,11 +177,11 @@ export function deconstructLinearOrFreeDrawElement(
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get the building components of a rectanguloid element in the form of
 | 
			
		||||
 * line segments and curves.
 | 
			
		||||
 * line segments and curves **unrotated**.
 | 
			
		||||
 *
 | 
			
		||||
 * @param element Target rectanguloid element
 | 
			
		||||
 * @param offset Optional offset to expand the rectanguloid shape
 | 
			
		||||
 * @returns Tuple of line segments (0) and curves (1)
 | 
			
		||||
 * @returns Tuple of **unrotated** line segments (0) and curves (1)
 | 
			
		||||
 */
 | 
			
		||||
export function deconstructRectanguloidElement(
 | 
			
		||||
  element: ExcalidrawRectanguloidElement,
 | 
			
		||||
@@ -310,12 +316,12 @@ export function deconstructRectanguloidElement(
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get the building components of a diamond element in the form of
 | 
			
		||||
 * line segments and curves as a tuple, in this order.
 | 
			
		||||
 * Get the **unrotated** building components of a diamond element
 | 
			
		||||
 * in the form of line segments and curves as a tuple, in this order.
 | 
			
		||||
 *
 | 
			
		||||
 * @param element The element to deconstruct
 | 
			
		||||
 * @param offset An optional offset
 | 
			
		||||
 * @returns Tuple of line segments (0) and curves (1)
 | 
			
		||||
 * @returns Tuple of line **unrotated** segments (0) and curves (1)
 | 
			
		||||
 */
 | 
			
		||||
export function deconstructDiamondElement(
 | 
			
		||||
  element: ExcalidrawDiamondElement,
 | 
			
		||||
 
 | 
			
		||||
@@ -4,12 +4,12 @@ import {
 | 
			
		||||
  polygonFromPoints,
 | 
			
		||||
  lineSegment,
 | 
			
		||||
  polygonIncludesPointNonZero,
 | 
			
		||||
  doBoundsIntersect,
 | 
			
		||||
} from "@excalidraw/math";
 | 
			
		||||
 | 
			
		||||
import {
 | 
			
		||||
  type Bounds,
 | 
			
		||||
  computeBoundTextPosition,
 | 
			
		||||
  doBoundsIntersect,
 | 
			
		||||
  getBoundTextElement,
 | 
			
		||||
  getElementBounds,
 | 
			
		||||
  intersectElementWithLineSegment,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,6 @@
 | 
			
		||||
import { type Bounds } from "@excalidraw/element";
 | 
			
		||||
 | 
			
		||||
import { isPoint, pointDistance, pointFrom, pointFromVector } from "./point";
 | 
			
		||||
import { vector, vectorNormal, vectorNormalize, vectorScale } from "./vector";
 | 
			
		||||
import { LegendreGaussN24CValues, LegendreGaussN24TValues } from "./constants";
 | 
			
		||||
import { doBoundsIntersect } from "./utils";
 | 
			
		||||
 | 
			
		||||
import type { Curve, GlobalPoint, LineSegment, LocalPoint } from "./types";
 | 
			
		||||
 | 
			
		||||
@@ -105,19 +102,6 @@ export const bezierEquation = <Point extends GlobalPoint | LocalPoint>(
 | 
			
		||||
export function curveIntersectLineSegment<
 | 
			
		||||
  Point extends GlobalPoint | LocalPoint,
 | 
			
		||||
>(c: Curve<Point>, l: LineSegment<Point>): Point[] {
 | 
			
		||||
  // Optimize by doing a cheap bounding box check first
 | 
			
		||||
  const b1 = curveBounds(c);
 | 
			
		||||
  const b2 = [
 | 
			
		||||
    Math.min(l[0][0], l[1][0]),
 | 
			
		||||
    Math.min(l[0][1], l[1][1]),
 | 
			
		||||
    Math.max(l[0][0], l[1][0]),
 | 
			
		||||
    Math.max(l[0][1], l[1][1]),
 | 
			
		||||
  ] as Bounds;
 | 
			
		||||
 | 
			
		||||
  if (!doBoundsIntersect(b1, b2)) {
 | 
			
		||||
    return [];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const line = (s: number) =>
 | 
			
		||||
    pointFrom<Point>(
 | 
			
		||||
      l[0][0] + s * (l[1][0] - l[0][0]),
 | 
			
		||||
@@ -295,15 +279,6 @@ export function curveTangent<Point extends GlobalPoint | LocalPoint>(
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function curveBounds<Point extends GlobalPoint | LocalPoint>(
 | 
			
		||||
  c: Curve<Point>,
 | 
			
		||||
): Bounds {
 | 
			
		||||
  const [P0, P1, P2, P3] = c;
 | 
			
		||||
  const x = [P0[0], P1[0], P2[0], P3[0]];
 | 
			
		||||
  const y = [P0[1], P1[1], P2[1], P3[1]];
 | 
			
		||||
  return [Math.min(...x), Math.min(...y), Math.max(...x), Math.max(...y)];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function curveCatmullRomQuadraticApproxPoints(
 | 
			
		||||
  points: GlobalPoint[],
 | 
			
		||||
  tension = 0.5,
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +10,12 @@ export function rectangle<P extends GlobalPoint | LocalPoint>(
 | 
			
		||||
  return [topLeft, bottomRight] as Rectangle<P>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function rectangleFromNumberSequence<
 | 
			
		||||
  Point extends LocalPoint | GlobalPoint,
 | 
			
		||||
>(minX: number, minY: number, maxX: number, maxY: number) {
 | 
			
		||||
  return rectangle(pointFrom<Point>(minX, minY), pointFrom<Point>(maxX, maxY));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function rectangleIntersectLineSegment<
 | 
			
		||||
  Point extends LocalPoint | GlobalPoint,
 | 
			
		||||
>(r: Rectangle<Point>, l: LineSegment<Point>): Point[] {
 | 
			
		||||
@@ -22,3 +28,12 @@ export function rectangleIntersectLineSegment<
 | 
			
		||||
    .map((s) => lineSegmentIntersectionPoints(l, s))
 | 
			
		||||
    .filter((i): i is Point => !!i);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function rectangleIntersectRectangle<
 | 
			
		||||
  Point extends LocalPoint | GlobalPoint,
 | 
			
		||||
>(rectangle1: Rectangle<Point>, rectangle2: Rectangle<Point>): boolean {
 | 
			
		||||
  const [[minX1, minY1], [maxX1, maxY1]] = rectangle1;
 | 
			
		||||
  const [[minX2, minY2], [maxX2, maxY2]] = rectangle2;
 | 
			
		||||
 | 
			
		||||
  return minX1 < maxX2 && maxX1 > minX2 && minY1 < maxY2 && maxY1 > minY2;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,3 @@
 | 
			
		||||
import { type Bounds } from "@excalidraw/element";
 | 
			
		||||
 | 
			
		||||
export const PRECISION = 10e-5;
 | 
			
		||||
 | 
			
		||||
export const clamp = (value: number, min: number, max: number) => {
 | 
			
		||||
@@ -33,17 +31,3 @@ export const isFiniteNumber = (value: any): value is number => {
 | 
			
		||||
 | 
			
		||||
export const isCloseTo = (a: number, b: number, precision = PRECISION) =>
 | 
			
		||||
  Math.abs(a - b) < precision;
 | 
			
		||||
 | 
			
		||||
export const doBoundsIntersect = (
 | 
			
		||||
  bounds1: Bounds | null,
 | 
			
		||||
  bounds2: Bounds | null,
 | 
			
		||||
): boolean => {
 | 
			
		||||
  if (bounds1 == null || bounds2 == null) {
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const [minX1, minY1, maxX1, maxY1] = bounds1;
 | 
			
		||||
  const [minX2, minY2, maxX2, maxY2] = bounds2;
 | 
			
		||||
 | 
			
		||||
  return minX1 < maxX2 && maxX1 > minX2 && minY1 < maxY2 && maxY1 > minY2;
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user