views:

1773

answers:

4

The polygon is given as a list of Vector2I objects (2 dimensional, integer coordinates). How can i test if a given point is inside? All implementations i found on the web fail for some trivial counter-example. It really seems to be hard to write a correct implementation. The language does not matter as i will port it myself.

+6  A: 

The Ray Casting or Winding methods are the most common for this problem. See the Wikipedia article for details.

Also, Check out this page for a well-documented solution in C.

e.James
For integer coordinates, wrf's code snippet will be more than sufficient.
Eric
+3  A: 

If it is convex, a trivial way to check it is that the point is to the same side of all the segments (if traversed in the same order). You can check that easily with the cross product.

Here is the code in Python:

#vertices is supposed a numpy.array,
#or any structure wich has the rest operator as an element by element operation
def inside_convex_polygon(point, vertices):
    sign = 0
    n_vertices = len(vertices)
    for n in xrange(n_vertices):
        segment = vertices[n], vertices[(n+1)%n_vertices]
        affine_segment = segment[1]-segment[0]
        affine_point = point-segment[0]
        k = x_product(affine_segment, affine_point)
        k = int(k / abs(k)) #normalized to 1 or -1
        if sign == 0: #the first case
            sign = k 
        elif k != sign:
             return False
    return True

def x_product(a, b):
     return a[0]*b[1]-a[1]*b[0]

I haven't tested it, but should work :-)

Edit: tested with a few trivial examples and seems to be working...

fortran
Hacking something together when there are well known solutions will almost always miss some edge cases.
Eric
try them and tell me if I'm wrong
fortran
A: 

Or from the man that wrote the book see - geometry page

Specifically this page, he discusses why winding rule is generally better than ray crossing.

edit - Sorry this isn't Jospeh O'Rourke who wrote the excellent book Computational Geometry in C, it's Paul Bourke but still a very very good source of geometry algorithms.

Martin Beckett
The page you cite then goes on to list the code snippet from WRF.
Eric
A: 

the way i know is something like that.

you pick a point somewhere outside the polygon it may be far away from the geometry. then you draw a line from this point. i mean you create a line equation with these two points.

then for every line in this polygon, you check if they intersect.

them sum of number of intersected lines give you it is inside or not.

if it is odd : inside

if it is even : outside

ufukgun
i just learned : it is Ray casting algorithm where eJames has already talked about
ufukgun
I find your explanation difficult to follow... what's the other point of the line?
fortran
Ray casting is generally a bad solution, it doesn't deal well with points that are near a vertex where the cast ray would be close to a side. Winding rule is much more robust and faster, especially for convex shapes
Martin Beckett
This solution is exactly what the code snippet from WRF does.
Eric
"what's the other point of the line?" any point which is garanteed to be outside of the polygon. for example: find minimum x and y for all points. pick x-100, y-100 is a point outside of the polygon.
ufukgun
@ufukgun, I'm smart enough to read that part, in the text say that's the "from" point, what is the "to"? It doesn't tell.
fortran
this point is the point that you want to test if it is inside?you have a point A and you want to know that if point A is inside the polygon. then you pick a random point B which is garanteed to be outside the polygon. Then you draw a line from A to B. you intersect with the lines on polygon. then you look the total number of intersection.
ufukgun