fix: Reduce allocations in collision detection (#9299)

Reduce allocations
This commit is contained in:
Márk Tolmács 2025-03-26 15:10:43 +01:00 committed by GitHub
parent ab89d4c16f
commit a18f059188
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -209,28 +209,28 @@ const intersectRectanguloidWithLineSegment = (
const [sides, corners] = deconstructRectanguloidElement(element, offset); const [sides, corners] = deconstructRectanguloidElement(element, offset);
return ( return (
[ // Test intersection against the sides, keep only the valid
// Test intersection against the sides, keep only the valid // intersection points and rotate them back to scene space
// intersection points and rotate them back to scene space sides
...sides .map((s) =>
.map((s) => lineSegmentIntersectionPoints(
lineSegmentIntersectionPoints( lineSegment<GlobalPoint>(rotatedA, rotatedB),
lineSegment<GlobalPoint>(rotatedA, rotatedB), s,
s, ),
), )
) .filter((x) => x != null)
.filter((x) => x != null) .map((j) => pointRotateRads<GlobalPoint>(j!, center, element.angle))
.map((j) => pointRotateRads<GlobalPoint>(j!, center, element.angle)),
// Test intersection against the corners which are cubic bezier curves, // Test intersection against the corners which are cubic bezier curves,
// keep only the valid intersection points and rotate them back to scene // keep only the valid intersection points and rotate them back to scene
// space // space
...corners .concat(
.flatMap((t) => corners
curveIntersectLineSegment(t, lineSegment(rotatedA, rotatedB)), .flatMap((t) =>
) curveIntersectLineSegment(t, lineSegment(rotatedA, rotatedB)),
.filter((i) => i != null) )
.map((j) => pointRotateRads(j, center, element.angle)), .filter((i) => i != null)
] .map((j) => pointRotateRads(j, center, element.angle)),
)
// Remove duplicates // Remove duplicates
.filter( .filter(
(p, idx, points) => points.findIndex((d) => pointsEqual(p, d)) === idx, (p, idx, points) => points.findIndex((d) => pointsEqual(p, d)) === idx,
@ -263,25 +263,25 @@ const intersectDiamondWithLineSegment = (
const [sides, curves] = deconstructDiamondElement(element, offset); const [sides, curves] = deconstructDiamondElement(element, offset);
return ( return (
[ sides
...sides .map((s) =>
.map((s) => lineSegmentIntersectionPoints(
lineSegmentIntersectionPoints( lineSegment<GlobalPoint>(rotatedA, rotatedB),
lineSegment<GlobalPoint>(rotatedA, rotatedB), s,
s, ),
), )
) .filter((p): p is GlobalPoint => p != null)
.filter((p): p is GlobalPoint => p != null) // Rotate back intersection points
// Rotate back intersection points .map((p) => pointRotateRads<GlobalPoint>(p!, center, element.angle))
.map((p) => pointRotateRads<GlobalPoint>(p!, center, element.angle)), .concat(
...curves curves
.flatMap((p) => .flatMap((p) =>
curveIntersectLineSegment(p, lineSegment(rotatedA, rotatedB)), curveIntersectLineSegment(p, lineSegment(rotatedA, rotatedB)),
) )
.filter((p) => p != null) .filter((p) => p != null)
// Rotate back intersection points // Rotate back intersection points
.map((p) => pointRotateRads(p, center, element.angle)), .map((p) => pointRotateRads(p, center, element.angle)),
] )
// Remove duplicates // Remove duplicates
.filter( .filter(
(p, idx, points) => points.findIndex((d) => pointsEqual(p, d)) === idx, (p, idx, points) => points.findIndex((d) => pointsEqual(p, d)) === idx,