def inside_polygon(x, y, coords, border_value):
    # should return the border value for point equal to any polygon vertex
    # TODO overflow possible with large values when comparing slopes, change procedure
    for c in coords[:]:
        if np.all(c == [x, y]):
            return border_value

    # and if the point p lies on any polygon edge
    p = np.array([x, y])
    p1 = coords[-1, :]
    for p2 in coords[:]:
        if (abs(
                AngleRepresentation(p1 - p).value -
                AngleRepresentation(p2 - p).value) == 2.0):
            return border_value
        p1 = p2

    contained = False
    # the edge from the last to the first point is checked first
    i = -1
    y1 = coords[-1, 1]
    y_gt_y1 = y > y1
    for y2 in coords[:, 1]:
        y_gt_y2 = y > y2
        if y_gt_y1:
            if not y_gt_y2:
                x1 = coords[i, 0]
                x2 = coords[i + 1, 0]
                # only crossings "right" of the point should be counted
                x1GEx = x <= x1
                x2GEx = x <= x2
                # compare the slope of the line [p1-p2] and [p-p2]
                # depending on the position of p2 this determines whether the polygon edge is right or left of the point
                # to avoid expensive division the divisors (of the slope dy/dx) are brought to the other side
                # ( dy/dx > a  ==  dy > a * dx )
                if (x1GEx and x2GEx) or ((x1GEx or x2GEx) and (y2 - y) *
                                         (x2 - x1) <= (y2 - y1) * (x2 - x)):
                    contained = not contained

        else:
            if y_gt_y2:
                x1 = coords[i, 0]
                x2 = coords[i + 1, 0]
                # only crossings "right" of the point should be counted
                x1GEx = x <= x1
                x2GEx = x <= x2
                if (x1GEx and x2GEx) or ((x1GEx or x2GEx) and (y2 - y) *
                                         (x2 - x1) >= (y2 - y1) * (x2 - x)):
                    contained = not contained

        y1 = y2
        y_gt_y1 = y_gt_y2
        i += 1

    return contained
示例#2
0
 def value_test_fct(input):
     np_2D_coord_vector = np.array(input)
     return AngleRepresentation(np_2D_coord_vector).value
示例#3
0
    def test_angle_repr(self):
        with pytest.raises(ValueError):
            AngleRepresentation(np.array([0.0, 0.0]))

        #
        # def quadrant_test_fct(input):
        #     np_2D_coord_vector = np.array(input)
        #     return AngleRepresentation(np_2D_coord_vector).quadrant
        #
        # data = [
        #     ([1.0, 0.0], 0.0),
        #     ([0.0, 1.0], 0.0),
        #     ([-1.0, 0.0], 1.0),
        #     ([0.0, -1.0], 3.0),
        #
        #     ([2.0, 0.0], 0.0),
        #     ([0.0, 2.0], 0.0),
        #     ([-2.0, 0.0], 1.0),
        #     ([0.0, -2.0], 3.0),
        #
        #     ([1.0, 1.0], 0.0),
        #     ([-1.0, 1.0], 1.0),
        #     ([-1.0, -1.0], 2.0),
        #     ([1.0, -1.0], 3.0),
        #
        #     ([1.0, 0.00001], 0.0),
        #     ([0.00001, 1.0], 0.0),
        #     ([-1.0, 0.00001], 1.0),
        #     ([0.00001, -1.0], 3.0),
        #
        #     ([1.0, -0.00001], 3.0),
        #     ([-0.00001, 1.0], 1.0),
        #     ([-1.0, -0.00001], 2.0),
        #     ([-0.00001, -1.0], 2.0),
        # ]
        #
        # proto_test_case(data, quadrant_test_fct)

        # TODO test:
        # randomized
        # every quadrant contains angle measures from 0.0 to 1.0
        # angle %360!
        #     rep(p1) > rep(p2) <=> angle(p1) > angle(p2)
        #     rep(p1) = rep(p2) <=> angle(p1) = angle(p2)
        # repr value in [0.0 : 4.0[

        def value_test_fct(input):
            np_2D_coord_vector = np.array(input)
            return AngleRepresentation(np_2D_coord_vector).value

        data = [
            ([1.0, 0.0], 0.0),
            ([0.0, 1.0], 1.0),
            ([-1.0, 0.0], 2.0),
            ([0.0, -1.0], 3.0),

            ([2.0, 0.0], 0.0),
            ([0.0, 2.0], 1.0),
            ([-2.0, 0.0], 2.0),
            ([0.0, -2.0], 3.0),
        ]

        proto_test_case(data, value_test_fct)