mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
Rectangle distance and tests
This commit is contained in:
parent
9a8aabbeca
commit
47cc842415
5 changed files with 72 additions and 25 deletions
39
packages/math/rectangle.test.ts
Normal file
39
packages/math/rectangle.test.ts
Normal file
|
@ -0,0 +1,39 @@
|
|||
import { point } from "./point";
|
||||
import { rectangle, rectangleDistanceFromPoint } from "./rectangle";
|
||||
|
||||
describe("rectangle distance", () => {
|
||||
it("finds the shortest distance", () => {
|
||||
expect(
|
||||
rectangleDistanceFromPoint(
|
||||
rectangle(point(-1, -1), point(1, 1)),
|
||||
point(2, 0),
|
||||
),
|
||||
).toBe(1);
|
||||
expect(
|
||||
rectangleDistanceFromPoint(
|
||||
rectangle(point(-1, -1), point(1, 1)),
|
||||
point(0, 2),
|
||||
),
|
||||
).toBe(1);
|
||||
expect(
|
||||
rectangleDistanceFromPoint(
|
||||
rectangle(point(-1, -1), point(1, 1)),
|
||||
point(-2, 0),
|
||||
),
|
||||
).toBe(1);
|
||||
expect(
|
||||
rectangleDistanceFromPoint(
|
||||
rectangle(point(-1, -1), point(1, 1)),
|
||||
point(0, -2),
|
||||
),
|
||||
).toBe(1);
|
||||
});
|
||||
it("finds the corner as closest point", () => {
|
||||
expect(
|
||||
rectangleDistanceFromPoint(
|
||||
rectangle(point(-1, -1), point(1, 1)),
|
||||
point(2, 2),
|
||||
),
|
||||
).toBe(Math.sqrt(2));
|
||||
});
|
||||
});
|
|
@ -1,19 +1,19 @@
|
|||
import { invariant } from "../excalidraw/utils";
|
||||
import { point } from "./point";
|
||||
import { segment, segmentDistanceToPoint } from "./segment";
|
||||
import type { GenericPoint, Rectangle } from "./types";
|
||||
|
||||
export function rectangle<P extends GenericPoint>(
|
||||
a: P,
|
||||
b: P,
|
||||
c: P,
|
||||
d: P,
|
||||
topLeft: P,
|
||||
bottomRight: P,
|
||||
): Rectangle<P> {
|
||||
return [a, b, c, d] as Rectangle<P>;
|
||||
return [topLeft, bottomRight] as Rectangle<P>;
|
||||
}
|
||||
|
||||
export function rectangleFromQuad<P extends GenericPoint>(
|
||||
quad: [a: P, b: P, c: P, d: P],
|
||||
export function rectangleFromPair<P extends GenericPoint>(
|
||||
pair: [a: P, b: P],
|
||||
): Rectangle<P> {
|
||||
return quad as Rectangle<P>;
|
||||
return pair as Rectangle<P>;
|
||||
}
|
||||
|
||||
export function rectangleFromArray<P extends GenericPoint>(
|
||||
|
@ -26,3 +26,17 @@ export function rectangleFromArray<P extends GenericPoint>(
|
|||
|
||||
return pointArray as Rectangle<P>;
|
||||
}
|
||||
|
||||
export function rectangleDistanceFromPoint<Point extends GenericPoint>(
|
||||
r: Rectangle<Point>,
|
||||
p: Point,
|
||||
): number {
|
||||
const sides = [
|
||||
segment(point(r[0][0], r[0][1]), point(r[1][0], r[0][1])),
|
||||
segment(point(r[1][0], r[0][1]), point(r[1][0], r[1][1])),
|
||||
segment(point(r[1][0], r[1][1]), point(r[0][0], r[1][1])),
|
||||
segment(point(r[0][0], r[1][1]), point(r[0][0], r[0][1])),
|
||||
];
|
||||
|
||||
return Math.min(...sides.map((side) => segmentDistanceToPoint(p, side)));
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { invariant } from "../excalidraw/utils";
|
||||
import {
|
||||
isPoint,
|
||||
pointCenter,
|
||||
|
@ -23,10 +22,9 @@ import {
|
|||
* @returns The line segment delineated by the points
|
||||
*/
|
||||
export function segment<P extends GenericPoint>(a: P, b: P): Segment<P> {
|
||||
invariant(
|
||||
!pointsEqual(a, b),
|
||||
"The start and end points of the segment cannot match",
|
||||
);
|
||||
if (pointsEqual(a, b)) {
|
||||
console.warn("The start and end points of the segment cannot match");
|
||||
}
|
||||
|
||||
return [a, b] as Segment<P>;
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ export type Triangle<P extends GenericPoint> = [a: P, b: P, c: P] & {
|
|||
/**
|
||||
* A rectangular shape represented by 4 points at its corners
|
||||
*/
|
||||
export type Rectangle<P extends GenericPoint> = [a: P, b: P, c: P, d: P] & {
|
||||
export type Rectangle<P extends GenericPoint> = [a: P, b: P] & {
|
||||
_brand: "excalimath__rectangle";
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue