0

I tried using the following code for the Even-Odd Rule from Wikipedia

# x, y -- x and y coordinates of point
# poly -- a list of tuples [(x, y), (x, y), ...]
def isPointInPath(x, y, poly):
        num = len(poly)
        i = 0
        j = num - 1
        c = False
        for i in range(num):
                if  ((poly[i][1] > y) != (poly[j][1] > y)) and \
                        (x < (poly[j][0] - poly[i][0]) * (y - poly[i][1]) / (poly[j][1] - poly[i][1]) + poly[i][0]):
                    c = not c
                j = i
        return c

Unfortuantely, it's giving wrong results for my simple rectilinear polygon when my test point is aligned with one of the horizontal edges

     -----
     |   |
     | x  ----|
  x  |--------|

Treating a horizontal edge as an edge makes both points regarded as within while ignoring the horizontal edge makes both points regarded as outside

So how can I make the even-odd rule work for such a polygon? Or suggest alternative algorithms?

Rufus
  • 5,111
  • 4
  • 28
  • 45
  • 1
    Intersect with a ray that is not axis aligned, e.g. ray on 45 deg. – Ante Jan 06 '17 at 12:07
  • does this mean that the even-odd rule (or any ray casting algorithm) won't work on polygons with edges parallel the the direction of ray cast? That's a major limitation isn't it? – Rufus Jan 07 '17 at 04:48
  • It can work with better handling of ray edge overlaps. If ray overlaps edge, than it is needed to check intersection with edge neighbours (previous and next edge.) Something like, move next edge to previous one in ray direction and check does ray intersect connected edges or only touch in one point. In case you draw ray intersects connected edges. If geometry is U shaped (add a part on right side) than ray will only touch connected edges. – Ante Jan 07 '17 at 09:17
  • I don't believe that the code doesn't work. In your example, for the upper cross, starting with the upper edge, clockwise, the if test will report false, false, false, true, false, false and the point is inside; for the lower cross, false, false, false, true, false, true and the point is outside. Can you give a numerical example ? –  Jan 12 '17 at 10:01

1 Answers1

1

The following rules taken from here seems to work

Edge Crossing Rules

an upward edge includes its starting endpoint, and excludes its final endpoint;

a downward edge excludes its starting endpoint, and includes its final endpoint;

horizontal edges are excluded

the edge-ray intersection point must be strictly right of the point P.

Note that the above rules follow the convention that

a point on a left or bottom edge is inside, and a point on a right or top edge is outside. This way, if two distinct polygons share a common boundary segment, then a point on that segment will be in one polygon or the other, but not both at the same time.

Also the author notes that this method only works for simple (non-self-intersecting) polygons. It also suggests using an efficient implementation of winding numbers instead which handles non-simple polygons better

Rufus
  • 5,111
  • 4
  • 28
  • 45