Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pointInShape returns incorrect value for multi-island polygons #26

Open
bryhoyt opened this issue Sep 13, 2022 · 0 comments
Open

pointInShape returns incorrect value for multi-island polygons #26

bryhoyt opened this issue Sep 13, 2022 · 0 comments

Comments

@bryhoyt
Copy link

bryhoyt commented Sep 13, 2022

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));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant