Linear distance calc
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
This commit is contained in:
parent
3b1c6444e2
commit
2082ef149c
@ -1,8 +1,8 @@
|
|||||||
import {
|
import {
|
||||||
curvePointDistance,
|
curvePointDistance,
|
||||||
distanceToLineSegment,
|
distanceToLineSegment,
|
||||||
lineSegment,
|
isCurve,
|
||||||
pointFrom,
|
isLineSegment,
|
||||||
pointRotateRads,
|
pointRotateRads,
|
||||||
} from "@excalidraw/math";
|
} from "@excalidraw/math";
|
||||||
|
|
||||||
@ -10,10 +10,16 @@ import { ellipse, ellipseDistanceFromPoint } from "@excalidraw/math/ellipse";
|
|||||||
|
|
||||||
import { elementCenterPoint } from "@excalidraw/common";
|
import { elementCenterPoint } from "@excalidraw/common";
|
||||||
|
|
||||||
import type { GlobalPoint, Radians } from "@excalidraw/math";
|
import type {
|
||||||
|
Curve,
|
||||||
|
GlobalPoint,
|
||||||
|
LineSegment,
|
||||||
|
Radians,
|
||||||
|
} from "@excalidraw/math";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
deconstructDiamondElement,
|
deconstructDiamondElement,
|
||||||
|
deconstructLinearOrFreeDrawElement,
|
||||||
deconstructRectanguloidElement,
|
deconstructRectanguloidElement,
|
||||||
} from "./utils";
|
} from "./utils";
|
||||||
|
|
||||||
@ -21,6 +27,8 @@ import type {
|
|||||||
ExcalidrawDiamondElement,
|
ExcalidrawDiamondElement,
|
||||||
ExcalidrawElement,
|
ExcalidrawElement,
|
||||||
ExcalidrawEllipseElement,
|
ExcalidrawEllipseElement,
|
||||||
|
ExcalidrawFreeDrawElement,
|
||||||
|
ExcalidrawLinearElement,
|
||||||
ExcalidrawRectanguloidElement,
|
ExcalidrawRectanguloidElement,
|
||||||
} from "./types";
|
} from "./types";
|
||||||
|
|
||||||
@ -45,20 +53,7 @@ export const distanceToElement = (
|
|||||||
case "line":
|
case "line":
|
||||||
case "arrow":
|
case "arrow":
|
||||||
case "freedraw":
|
case "freedraw":
|
||||||
return element.points.reduce((acc, point, idx) => {
|
return distanceToLinearOrFreeDraElement(element, p);
|
||||||
if (idx === 0) {
|
|
||||||
return acc;
|
|
||||||
}
|
|
||||||
const prevPoint = element.points[idx - 1];
|
|
||||||
const segment = lineSegment(
|
|
||||||
pointFrom<GlobalPoint>(
|
|
||||||
element.x + prevPoint[0],
|
|
||||||
element.y + prevPoint[1],
|
|
||||||
),
|
|
||||||
pointFrom<GlobalPoint>(element.x + point[0], element.y + point[1]),
|
|
||||||
);
|
|
||||||
return Math.min(acc, distanceToLineSegment(p, segment));
|
|
||||||
}, Infinity);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -137,3 +132,36 @@ const distanceToEllipseElement = (
|
|||||||
ellipse(center, element.width / 2, element.height / 2),
|
ellipse(center, element.width / 2, element.height / 2),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user