Is my point-in-polygon adaptation (ordan curve theorem) in python correct?

Problem

I recently found it necessary to determine if my points are inside a polygon. So I found out about this approach in C ++ and adapted it to python. However, the C ++ code I studied is not quite right, I think? I think I fixed it, but I'm not quite sure, so I was hoping that people are brighter than me, can help me lighten this up a bit?

The theorem is super simple, and the idea is that with the nth closed polygon, you draw an arbitrary line, if your point is inside, your line will intersect with edges an odd number of times. Otherwise, you will be flat and out of range. Pretty noisy cool.

I had the following test cases:

    polygon_x = [5, 5, 11, 10]
    polygon_y = [5, 10, 5, 10]
    test1_x = 6
    test1_y = 6

    result1 = point_in_polygon(test1_x, test1_y, polygon_x, polygon_y)
    print(result1)

    test2_x = 13
    test2_y = 5
    result2 = point_in_polygon(test2_x, test2_y, polygon_x, polygon_y)
    print(result2)

, :

            if polygon_x[i] < polygon_x[(i+1) % length]:
                temp_x = polygon_x[i]
                temp_y = polygon_x[(i+1) % length]
            else:
                temp_x = polygon_x[(i+1) % length]
                temp_y = polygon_x[i]

! true result1, false result2. , - .

, ++, , . , , , temp_y polygon_y, polygon_x. , , (6,6) . , , , . .

, python

    def point_in_polygon(self, target_x, target_y, polygon_x, polygon_y):
        print(polygon_x)
        print(polygon_y)
        #Variable to track how many times ray crosses a line segment
        crossings = 0
        temp_x = 0
        temp_y = 0
        length = len(polygon_x)

        for i in range(0,length):

            if polygon_x[i] < polygon_x[(i+1) % length]:
                temp_x = polygon_x[i]
                temp_y = polygon_y[(i+1) % length]
            else:
                temp_x = polygon_x[(i+1) % length]
                temp_y = polygon_y[i]

            print(str(temp_x) + ", " + str(temp_y))

            #check
            if target_x > temp_x and target_x <= temp_y and (target_y < polygon_y[i] or target_y <= polygon_y[(i+1)%length]):
                eps = 0.000001

                dx = polygon_x[(i+1) % length] - polygon_x[i]
                dy = polygon_y[(i+1) % length] - polygon_y[i]

                k = 0
                if abs(dx) < eps:
                    k = 999999999999999999999999999
                else:
                    k = dy/dx

                m = polygon_y[i] - k * polygon_x[i]
                y2 = k*target_x + m

                if target_y <= y2:
                    crossings += 1
        print(crossings)
        if crossings % 2 == 1:
            return True
        else:
            return False

- , temp_x temp_y? , temp_x polygon_x temp_y polygon_y - ? . .

, temp_x temp_y, . i = 0, , polygon_x[0] < polygon_x[1] false, temp_x[1] = 5 temp_y[0] = 5. (5,5). . , , ( , ), - :

x = [5, 10, 10, 5]
y = [10,10, 5, 5]

, i = 0, temp_x[1] = 10 temp_y[0] = 10. , (10,10). "" (9,9), . , , , . , , , , - ?

, , , - . n-, , . , , .

, . .

+4
1

, x1 x2 ++-, , Python. x, temp_y . min_x max_x, x , . :

for i in range(length):
    min_x = min(polygon_x[i], polygon_x[(i+1)%length])
    max_x = max(polygon_x[i], polygon_x[(i+1)%length])

    if x_min < target_x <= x_max:
        # ...

, , , ++, min max .

, , temp_y polygon_x. , ( , , ). , .

, (polygon_x = [5, 5, 11, 10] polygon_y = [5, 10, 5, 10]), . , ( ) -, , , x . .

, , (, , , (10, 10) , (5, 5)). , , < <=. "".

(, , 11 10), - . (6, 6) , , y temp.

+3

Source: https://habr.com/ru/post/1653236/


All Articles