Skip to content

Instantly share code, notes, and snippets.

@vlasky
Last active March 19, 2024 04:58
Show Gist options
  • Star 18 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save vlasky/d0d1d97af30af3191fc214beaf379acc to your computer and use it in GitHub Desktop.
Save vlasky/d0d1d97af30af3191fc214beaf379acc to your computer and use it in GitHub Desktop.
JavaScript implementation of winding number algorithm to determine whether a point is inside a polygon
//JavaScript implementation of winding number algorithm to determine whether a point is inside a polygon
//Based on C++ implementation of wn_PnPoly() published on http://geomalgorithms.com/a03-_inclusion.html
function pointInPolygon(point, vs) {
const x = point[0], y = point[1];
let wn = 0;
for (let i = 0, j = vs.length - 1; i < vs.length; j = i++) {
let xi = vs[i][0], yi = vs[i][1];
let xj = vs[j][0], yj = vs[j][1];
if (yj <= y) {
if (yi > y) {
if (isLeft([xj, yj], [xi, yi], [x,y]) > 0) {
wn++;
}
}
} else {
if (yi <= y) {
if (isLeft([xj, yj], [xi, yi], [x, y]) < 0) {
wn--;
}
}
}
}
return wn != 0;
};
function isLeft(P0, P1, P2) {
let res = ( (P1[0] - P0[0]) * (P2[1] - P0[1])
- (P2[0] - P0[0]) * (P1[1] - P0[1]) );
return res;
}
@gmac
Copy link

gmac commented Mar 9, 2021

A bit more terse and using TypeScript, assume Point is a type with x and y number properties...

function cross(x: Point, y: Point, z: Point): number {
  return (y.x - x.x) * (z.y - x.y) - (z.x - x.x) * (y.y - x.y);
}

function pointInPolygon(p: Point, points: Array<Point>): boolean {
  let wn = 0; // winding number

  points.forEach((a, i) => {
    const b = points[(i+1) % points.length];
    if (a.y <= p.y) {
      if (b.y > p.y && cross(a, b, p) > 0) {
        wn += 1;
      }
    } else if (b.y <= p.y && cross(a, b, p) < 0) {
      wn -= 1;
    }
  });

  return wn !== 0;
}

@mturoci
Copy link

mturoci commented Sep 27, 2022

Thanks @gmac! Works perfectly :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment