-
Notifications
You must be signed in to change notification settings - Fork 12
Open
Description
For polygons with holes that have sub-polygons (islands) inside the holes, pointInShape will incorrectly return false in many scenarios where it should return true.
In the test below (which is inside a loop on this.paths):
if (!pointInPath && orientation || pointInPath && !orientation) {
return false;
}
if there is at least one island where the condition !pointInPath && orientation holds true (and if there are multiple non-overlapping islands, there can be at most one which contains the point, so there will always be at least one which does not contain the point) then the function will exit and report the point is not in the shape -- even though it may be in one of the islands.
I've replaced it in my own code with the following, which you're welcome to use. Note that it also handles nested islands:
function pointInSubPolys(point) {
const indices = [...this.paths.keys()];
const polys = indices.filter((idx) => this.orientation(idx) && this.pointInPath(idx, point));
const holes = indices.filter((idx) => !this.orientation(idx) && this.pointInPath(idx, point));
// Important: just being in a hole poly does not mean it's in the hole, because it
// could be in an island *inside* the hole. So check the even/odd count.
const inShape = polys.length && polys.length % 2 !== holes.length % 2;
return inShape ? polys : undefined;
}
public pointInShape(point) {
return Boolean(this.pointInSubPolys(point));
}
louisptremblay
Metadata
Metadata
Assignees
Labels
No labels