class OsmNogoPolygon extends OsmNodeNamed {

  public boolean isWithin(final long px, final long py)
  {
    int wn = 0; // the winding number counter

    // loop through all edges of the polygon
    final int i_last = points.size()-1;
    final Point p0 = points.get(isClosed ? i_last : 0);
    long p0x = p0.x; // need to use long to avoid overflow in products
    long p0y = p0.y;

    for (int i = isClosed ? 0 : 1; i <= i_last; i++) // edge from v[i] to v[i+1]
    {
      final Point p1 = points.get(i);

      final long p1x = p1.x;
      final long p1y = p1.y;

      if (OsmNogoPolygon.isOnLine(px, py, p0x, p0y, p1x, p1y))
      {
        return true;
      }

      if (p0y <= py)  // start y <= p.y
      {
        if (p1y > py) // an upward crossing
        {             // p left of edge
          if (((p1x - p0x) * (py - p0y) - (px - p0x) * (p1y - p0y)) > 0)
          {
            ++wn;     // have a valid up intersect
          }
        }
      }
      else // start y > p.y (no test needed)
      {
        if (p1y <= py) // a downward crossing
        {              // p right of edge
          if (((p1x - p0x) * (py - p0y) - (px - p0x) * (p1y - p0y)) < 0)
          {
            --wn;      // have a valid down intersect
          }
        }
      }
      p0x = p1x;
      p0y = p1y;
    }
    return wn != 0;
  }

  public  OsmNogoPolygon(boolean closed);

}