Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
This commit is contained in:
Mark Tolmacs 2025-05-18 20:23:53 +02:00
parent 624b9927cd
commit bcdcb21971
No known key found for this signature in database
3 changed files with 30 additions and 75 deletions

View File

@ -5,8 +5,6 @@ import {
} from "@excalidraw/common";
import {
curveIntersectLineSegment,
isCurve,
isLineSegment,
isPointWithinBounds,
lineSegment,
lineSegmentIntersectionPoints,
@ -24,12 +22,7 @@ import {
ellipseSegmentInterceptPoints,
} from "@excalidraw/math/ellipse";
import type {
Curve,
GlobalPoint,
LineSegment,
Radians,
} from "@excalidraw/math";
import type { GlobalPoint, LineSegment, Radians } from "@excalidraw/math";
import type { FrameNameBounds } from "@excalidraw/excalidraw/types";
@ -218,33 +211,13 @@ const intersectLinearOrFreeDrawWithLineSegment = (
element: ExcalidrawLinearElement | ExcalidrawFreeDrawElement,
segment: LineSegment<GlobalPoint>,
): GlobalPoint[] => {
const shapes = deconstructLinearOrFreeDrawElement(element);
const intersections: GlobalPoint[] = [];
for (const shape of shapes) {
switch (true) {
case isCurve(shape):
//debugDrawCubicBezier(shape);
intersections.push(
...curveIntersectLineSegment(shape as Curve<GlobalPoint>, segment),
);
continue;
case isLineSegment(shape):
//debugDrawLine(shape);
const point = lineSegmentIntersectionPoints(
segment,
shape as LineSegment<GlobalPoint>,
);
if (point) {
intersections.push(point);
}
continue;
}
}
return intersections;
const [lines, curves] = deconstructLinearOrFreeDrawElement(element);
return [
...lines
.map((l) => lineSegmentIntersectionPoints(l, segment))
.filter((p): p is GlobalPoint => p != null),
...curves.flatMap((c) => curveIntersectLineSegment(c, segment)),
].sort();
};
const intersectRectanguloidWithLineSegment = (

View File

@ -1,8 +1,6 @@
import {
curvePointDistance,
distanceToLineSegment,
isCurve,
isLineSegment,
pointRotateRads,
} from "@excalidraw/math";
@ -10,12 +8,7 @@ import { ellipse, ellipseDistanceFromPoint } from "@excalidraw/math/ellipse";
import { elementCenterPoint } from "@excalidraw/common";
import type {
Curve,
GlobalPoint,
LineSegment,
Radians,
} from "@excalidraw/math";
import type { GlobalPoint, Radians } from "@excalidraw/math";
import {
deconstructDiamondElement,
@ -137,31 +130,9 @@ const distanceToLinearOrFreeDraElement = (
element: ExcalidrawLinearElement | ExcalidrawFreeDrawElement,
p: GlobalPoint,
) => {
const shapes = deconstructLinearOrFreeDrawElement(element);
let distance = Infinity;
for (const shape of shapes) {
switch (true) {
case isCurve(shape): {
const d = curvePointDistance(shape as Curve<GlobalPoint>, p);
if (d < distance) {
distance = d;
}
continue;
}
case isLineSegment(shape): {
const d = distanceToLineSegment(p, shape as LineSegment<GlobalPoint>);
if (d < distance) {
distance = d;
}
continue;
}
}
}
return distance;
const [lines, curves] = deconstructLinearOrFreeDrawElement(element);
return Math.min(
...lines.map((s) => distanceToLineSegment(p, s)),
...curves.map((a) => curvePointDistance(a, p)),
);
};

View File

@ -19,19 +19,30 @@ import { generateLinearCollisionShape } from "./Shape";
import type {
ExcalidrawDiamondElement,
ExcalidrawElement,
ExcalidrawFreeDrawElement,
ExcalidrawLinearElement,
ExcalidrawRectanguloidElement,
} from "./types";
type ElementShape = [LineSegment<GlobalPoint>[], Curve<GlobalPoint>[]];
class ElementShapeCache {
private static cache = new WeakMap<
ExcalidrawElement,
Map<number, ElementShape>
>();
}
export function deconstructLinearOrFreeDrawElement(
element: ExcalidrawLinearElement | ExcalidrawFreeDrawElement,
): (Curve<GlobalPoint> | LineSegment<GlobalPoint>)[] {
): [LineSegment<GlobalPoint>[], Curve<GlobalPoint>[]] {
const ops = generateLinearCollisionShape(element) as {
op: string;
data: number[];
}[];
const components = [];
const lines = [];
const curves = [];
for (let idx = 0; idx < ops.length; idx += 1) {
const op = ops[idx];
@ -45,7 +56,7 @@ export function deconstructLinearOrFreeDrawElement(
throw new Error("prevPoint is undefined");
}
components.push(
lines.push(
lineSegment<GlobalPoint>(
pointFrom<GlobalPoint>(
element.x + prevPoint[0],
@ -63,7 +74,7 @@ export function deconstructLinearOrFreeDrawElement(
throw new Error("prevPoint is undefined");
}
components.push(
curves.push(
curve<GlobalPoint>(
pointFrom<GlobalPoint>(
element.x + prevPoint[0],
@ -90,7 +101,7 @@ export function deconstructLinearOrFreeDrawElement(
}
}
return components;
return [lines, curves];
}
/**