nonzero enclosure

This commit is contained in:
Ryan Di 2025-04-07 23:57:14 +10:00
parent 9a6330bad9
commit 98000be0e0
2 changed files with 34 additions and 1 deletions

View file

@ -5,6 +5,7 @@ import {
polygonIncludesPoint, polygonIncludesPoint,
lineSegment, lineSegment,
lineSegmentIntersectionPoints, lineSegmentIntersectionPoints,
polygonIncludesPointNonZero,
} from "@excalidraw/math"; } from "@excalidraw/math";
import type { GlobalPoint, LineSegment } from "@excalidraw/math/types"; import type { GlobalPoint, LineSegment } from "@excalidraw/math/types";
@ -73,7 +74,9 @@ const enclosureTest = (
} }
return segments.some((segment) => { return segments.some((segment) => {
return segment.some((point) => polygonIncludesPoint(point, lassoPolygon)); return segment.some((point) =>
polygonIncludesPointNonZero(point, lassoPolygon),
);
}); });
}; };

View file

@ -41,6 +41,36 @@ export const polygonIncludesPoint = <Point extends LocalPoint | GlobalPoint>(
return inside; return inside;
}; };
export const polygonIncludesPointNonZero = <Point extends [number, number]>(
point: Point,
polygon: Point[],
): boolean => {
const [x, y] = point;
let windingNumber = 0;
for (let i = 0; i < polygon.length; i++) {
const j = (i + 1) % polygon.length;
const [xi, yi] = polygon[i];
const [xj, yj] = polygon[j];
if (yi <= y) {
if (yj > y) {
if ((xj - xi) * (y - yi) - (x - xi) * (yj - yi) > 0) {
windingNumber++;
}
}
} else {
if (yj <= y) {
if ((xj - xi) * (y - yi) - (x - xi) * (yj - yi) < 0) {
windingNumber--;
}
}
}
}
return windingNumber !== 0;
};
export const pointOnPolygon = <Point extends LocalPoint | GlobalPoint>( export const pointOnPolygon = <Point extends LocalPoint | GlobalPoint>(
p: Point, p: Point,
poly: Polygon<Point>, poly: Polygon<Point>,