From a18f059188b8dd978a9162cf5c70ac725025910b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rk=20Tolm=C3=A1cs?= Date: Wed, 26 Mar 2025 15:10:43 +0100 Subject: [PATCH] fix: Reduce allocations in collision detection (#9299) Reduce allocations --- packages/excalidraw/element/collision.ts | 76 ++++++++++++------------ 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/packages/excalidraw/element/collision.ts b/packages/excalidraw/element/collision.ts index a86cbd62f..931b8c800 100644 --- a/packages/excalidraw/element/collision.ts +++ b/packages/excalidraw/element/collision.ts @@ -209,28 +209,28 @@ const intersectRectanguloidWithLineSegment = ( const [sides, corners] = deconstructRectanguloidElement(element, offset); return ( - [ - // Test intersection against the sides, keep only the valid - // intersection points and rotate them back to scene space - ...sides - .map((s) => - lineSegmentIntersectionPoints( - lineSegment(rotatedA, rotatedB), - s, - ), - ) - .filter((x) => x != null) - .map((j) => pointRotateRads(j!, center, element.angle)), + // Test intersection against the sides, keep only the valid + // intersection points and rotate them back to scene space + sides + .map((s) => + lineSegmentIntersectionPoints( + lineSegment(rotatedA, rotatedB), + s, + ), + ) + .filter((x) => x != null) + .map((j) => pointRotateRads(j!, center, element.angle)) // Test intersection against the corners which are cubic bezier curves, // keep only the valid intersection points and rotate them back to scene // space - ...corners - .flatMap((t) => - curveIntersectLineSegment(t, lineSegment(rotatedA, rotatedB)), - ) - .filter((i) => i != null) - .map((j) => pointRotateRads(j, center, element.angle)), - ] + .concat( + corners + .flatMap((t) => + curveIntersectLineSegment(t, lineSegment(rotatedA, rotatedB)), + ) + .filter((i) => i != null) + .map((j) => pointRotateRads(j, center, element.angle)), + ) // Remove duplicates .filter( (p, idx, points) => points.findIndex((d) => pointsEqual(p, d)) === idx, @@ -263,25 +263,25 @@ const intersectDiamondWithLineSegment = ( const [sides, curves] = deconstructDiamondElement(element, offset); return ( - [ - ...sides - .map((s) => - lineSegmentIntersectionPoints( - lineSegment(rotatedA, rotatedB), - s, - ), - ) - .filter((p): p is GlobalPoint => p != null) - // Rotate back intersection points - .map((p) => pointRotateRads(p!, center, element.angle)), - ...curves - .flatMap((p) => - curveIntersectLineSegment(p, lineSegment(rotatedA, rotatedB)), - ) - .filter((p) => p != null) - // Rotate back intersection points - .map((p) => pointRotateRads(p, center, element.angle)), - ] + sides + .map((s) => + lineSegmentIntersectionPoints( + lineSegment(rotatedA, rotatedB), + s, + ), + ) + .filter((p): p is GlobalPoint => p != null) + // Rotate back intersection points + .map((p) => pointRotateRads(p!, center, element.angle)) + .concat( + curves + .flatMap((p) => + curveIntersectLineSegment(p, lineSegment(rotatedA, rotatedB)), + ) + .filter((p) => p != null) + // Rotate back intersection points + .map((p) => pointRotateRads(p, center, element.angle)), + ) // Remove duplicates .filter( (p, idx, points) => points.findIndex((d) => pointsEqual(p, d)) === idx,