Refactor
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
This commit is contained in:
parent
624b9927cd
commit
bcdcb21971
@ -5,8 +5,6 @@ import {
|
|||||||
} from "@excalidraw/common";
|
} from "@excalidraw/common";
|
||||||
import {
|
import {
|
||||||
curveIntersectLineSegment,
|
curveIntersectLineSegment,
|
||||||
isCurve,
|
|
||||||
isLineSegment,
|
|
||||||
isPointWithinBounds,
|
isPointWithinBounds,
|
||||||
lineSegment,
|
lineSegment,
|
||||||
lineSegmentIntersectionPoints,
|
lineSegmentIntersectionPoints,
|
||||||
@ -24,12 +22,7 @@ import {
|
|||||||
ellipseSegmentInterceptPoints,
|
ellipseSegmentInterceptPoints,
|
||||||
} from "@excalidraw/math/ellipse";
|
} from "@excalidraw/math/ellipse";
|
||||||
|
|
||||||
import type {
|
import type { GlobalPoint, LineSegment, Radians } from "@excalidraw/math";
|
||||||
Curve,
|
|
||||||
GlobalPoint,
|
|
||||||
LineSegment,
|
|
||||||
Radians,
|
|
||||||
} from "@excalidraw/math";
|
|
||||||
|
|
||||||
import type { FrameNameBounds } from "@excalidraw/excalidraw/types";
|
import type { FrameNameBounds } from "@excalidraw/excalidraw/types";
|
||||||
|
|
||||||
@ -218,33 +211,13 @@ const intersectLinearOrFreeDrawWithLineSegment = (
|
|||||||
element: ExcalidrawLinearElement | ExcalidrawFreeDrawElement,
|
element: ExcalidrawLinearElement | ExcalidrawFreeDrawElement,
|
||||||
segment: LineSegment<GlobalPoint>,
|
segment: LineSegment<GlobalPoint>,
|
||||||
): GlobalPoint[] => {
|
): GlobalPoint[] => {
|
||||||
const shapes = deconstructLinearOrFreeDrawElement(element);
|
const [lines, curves] = deconstructLinearOrFreeDrawElement(element);
|
||||||
const intersections: GlobalPoint[] = [];
|
return [
|
||||||
|
...lines
|
||||||
for (const shape of shapes) {
|
.map((l) => lineSegmentIntersectionPoints(l, segment))
|
||||||
switch (true) {
|
.filter((p): p is GlobalPoint => p != null),
|
||||||
case isCurve(shape):
|
...curves.flatMap((c) => curveIntersectLineSegment(c, segment)),
|
||||||
//debugDrawCubicBezier(shape);
|
].sort();
|
||||||
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 intersectRectanguloidWithLineSegment = (
|
const intersectRectanguloidWithLineSegment = (
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
curvePointDistance,
|
curvePointDistance,
|
||||||
distanceToLineSegment,
|
distanceToLineSegment,
|
||||||
isCurve,
|
|
||||||
isLineSegment,
|
|
||||||
pointRotateRads,
|
pointRotateRads,
|
||||||
} from "@excalidraw/math";
|
} from "@excalidraw/math";
|
||||||
|
|
||||||
@ -10,12 +8,7 @@ import { ellipse, ellipseDistanceFromPoint } from "@excalidraw/math/ellipse";
|
|||||||
|
|
||||||
import { elementCenterPoint } from "@excalidraw/common";
|
import { elementCenterPoint } from "@excalidraw/common";
|
||||||
|
|
||||||
import type {
|
import type { GlobalPoint, Radians } from "@excalidraw/math";
|
||||||
Curve,
|
|
||||||
GlobalPoint,
|
|
||||||
LineSegment,
|
|
||||||
Radians,
|
|
||||||
} from "@excalidraw/math";
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
deconstructDiamondElement,
|
deconstructDiamondElement,
|
||||||
@ -137,31 +130,9 @@ const distanceToLinearOrFreeDraElement = (
|
|||||||
element: ExcalidrawLinearElement | ExcalidrawFreeDrawElement,
|
element: ExcalidrawLinearElement | ExcalidrawFreeDrawElement,
|
||||||
p: GlobalPoint,
|
p: GlobalPoint,
|
||||||
) => {
|
) => {
|
||||||
const shapes = deconstructLinearOrFreeDrawElement(element);
|
const [lines, curves] = deconstructLinearOrFreeDrawElement(element);
|
||||||
let distance = Infinity;
|
return Math.min(
|
||||||
|
...lines.map((s) => distanceToLineSegment(p, s)),
|
||||||
for (const shape of shapes) {
|
...curves.map((a) => curvePointDistance(a, p)),
|
||||||
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;
|
|
||||||
};
|
};
|
||||||
|
@ -19,19 +19,30 @@ import { generateLinearCollisionShape } from "./Shape";
|
|||||||
|
|
||||||
import type {
|
import type {
|
||||||
ExcalidrawDiamondElement,
|
ExcalidrawDiamondElement,
|
||||||
|
ExcalidrawElement,
|
||||||
ExcalidrawFreeDrawElement,
|
ExcalidrawFreeDrawElement,
|
||||||
ExcalidrawLinearElement,
|
ExcalidrawLinearElement,
|
||||||
ExcalidrawRectanguloidElement,
|
ExcalidrawRectanguloidElement,
|
||||||
} from "./types";
|
} from "./types";
|
||||||
|
|
||||||
|
type ElementShape = [LineSegment<GlobalPoint>[], Curve<GlobalPoint>[]];
|
||||||
|
|
||||||
|
class ElementShapeCache {
|
||||||
|
private static cache = new WeakMap<
|
||||||
|
ExcalidrawElement,
|
||||||
|
Map<number, ElementShape>
|
||||||
|
>();
|
||||||
|
}
|
||||||
|
|
||||||
export function deconstructLinearOrFreeDrawElement(
|
export function deconstructLinearOrFreeDrawElement(
|
||||||
element: ExcalidrawLinearElement | ExcalidrawFreeDrawElement,
|
element: ExcalidrawLinearElement | ExcalidrawFreeDrawElement,
|
||||||
): (Curve<GlobalPoint> | LineSegment<GlobalPoint>)[] {
|
): [LineSegment<GlobalPoint>[], Curve<GlobalPoint>[]] {
|
||||||
const ops = generateLinearCollisionShape(element) as {
|
const ops = generateLinearCollisionShape(element) as {
|
||||||
op: string;
|
op: string;
|
||||||
data: number[];
|
data: number[];
|
||||||
}[];
|
}[];
|
||||||
const components = [];
|
const lines = [];
|
||||||
|
const curves = [];
|
||||||
|
|
||||||
for (let idx = 0; idx < ops.length; idx += 1) {
|
for (let idx = 0; idx < ops.length; idx += 1) {
|
||||||
const op = ops[idx];
|
const op = ops[idx];
|
||||||
@ -45,7 +56,7 @@ export function deconstructLinearOrFreeDrawElement(
|
|||||||
throw new Error("prevPoint is undefined");
|
throw new Error("prevPoint is undefined");
|
||||||
}
|
}
|
||||||
|
|
||||||
components.push(
|
lines.push(
|
||||||
lineSegment<GlobalPoint>(
|
lineSegment<GlobalPoint>(
|
||||||
pointFrom<GlobalPoint>(
|
pointFrom<GlobalPoint>(
|
||||||
element.x + prevPoint[0],
|
element.x + prevPoint[0],
|
||||||
@ -63,7 +74,7 @@ export function deconstructLinearOrFreeDrawElement(
|
|||||||
throw new Error("prevPoint is undefined");
|
throw new Error("prevPoint is undefined");
|
||||||
}
|
}
|
||||||
|
|
||||||
components.push(
|
curves.push(
|
||||||
curve<GlobalPoint>(
|
curve<GlobalPoint>(
|
||||||
pointFrom<GlobalPoint>(
|
pointFrom<GlobalPoint>(
|
||||||
element.x + prevPoint[0],
|
element.x + prevPoint[0],
|
||||||
@ -90,7 +101,7 @@ export function deconstructLinearOrFreeDrawElement(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return components;
|
return [lines, curves];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user