11# -*- coding: utf-8 -*-
22"""
33"""
4- from numpy import empty, where
4+ from numpy import empty, where, array
55from numba import njit, prange, types as numba_types
6+ from Polygon import Polygon
67
78
89@njit(cache=True)
@@ -17,7 +18,9 @@ def is_left(x_line_0, y_line_0, x_line_1, y_line_1, x_test, y_test):
1718 See: Algorithm 1 "Area of Triangles and Polygons"
1819 """
1920 # Vector product
20- product = (x_line_1 - x_line_0) * (y_test - y_line_0) - (x_test - x_line_0) * (y_line_1 - y_line_0)
21+ product = (x_line_1 - x_line_0) * (y_test - y_line_0) - (x_test - x_line_0) * (
22+ y_line_1 - y_line_0
23+ )
2124 return product > 0
2225
2326
@@ -50,21 +53,13 @@ def winding_number_poly(x, y, xy_poly):
5053 y_next = xy_poly[i_elt + 1, 1]
5154 if xy_poly[i_elt, 1] <= y:
5255 if y_next > y:
53- if is_left(xy_poly[i_elt, 0],
54- xy_poly[i_elt, 1],
55- x_next,
56- y_next,
57- x, y
58- ):
56+ if is_left(xy_poly[i_elt, 0], xy_poly[i_elt, 1], x_next, y_next, x, y):
5957 wn += 1
6058 else:
6159 if y_next <= y:
62- if not is_left(xy_poly[i_elt, 0],
63- xy_poly[i_elt, 1],
64- x_next,
65- y_next,
66- x, y
67- ):
60+ if not is_left(
61+ xy_poly[i_elt, 0], xy_poly[i_elt, 1], x_next, y_next, x, y
62+ ):
6863 wn -= 1
6964 return wn
7065
@@ -92,3 +87,58 @@ def winding_number_grid_in_poly(x_1d, y_1d, i_x0, i_x1, x_size, i_y0, xy_poly):
9287 if i_x1 < i_x0:
9388 i_x %= x_size
9489 return i_x, i_y
90+
91+
92+ @njit(cache=True, fastmath=True)
93+ def bbox_intersection(x0, y0, x1, y1):
94+ """compute bbox to check if there are a bbox intersection
95+ """
96+ nb0 = x0.shape[0]
97+ nb1 = x1.shape[0]
98+ x1_min, y1_min = empty(nb1), empty(nb1)
99+ x1_max, y1_max = empty(nb1), empty(nb1)
100+ for i1 in range(nb1):
101+ x1_min[i1], y1_min[i1] = x1[i1].min(), y1[i1].min()
102+ x1_max[i1], y1_max[i1] = x1[i1].max(), y1[i1].max()
103+
104+ i, j = list(), list()
105+ for i0 in range(nb0):
106+ x_in_min, y_in_min = x0[i0].min(), y0[i0].min()
107+ x_in_max, y_in_max = x0[i0].max(), y0[i0].max()
108+ for i1 in range(nb1):
109+ if y_in_max < y1_min[i1] or y_in_min > y1_max[i1]:
110+ continue
111+ x1_min_ = x1_min[i1]
112+ x1_max_ = x1_max[i1]
113+ if abs(x_in_min - x1_min_) > 180:
114+ ref = x_in_min - 180
115+ x1_min_ = (x1_min_ - ref) % 360 + ref
116+ x1_max_ = (x1_max_ - ref) % 360 + ref
117+ if x_in_max < x1_min_ or x_in_min > x1_max_:
118+ continue
119+ i.append(i0)
120+ j.append(i1)
121+ return array(i), array(j)
122+
123+
124+ @njit(cache=True, fastmath=True)
125+ def create_vertice(x, y):
126+ nb = x.shape[0]
127+ v = empty((nb, 2))
128+ for i in range(nb):
129+ v[i, 0] = x[i]
130+ v[i, 1] = y[i]
131+ return v
132+
133+
134+ def common_area(x0, y0, x1, y1):
135+ nb, _ = x0.shape
136+ cost = empty((nb))
137+ for i in range(nb):
138+ x0_, x1_ = x0[i], x1[i]
139+ if abs(x0_[0] - x1_[0]) > 180:
140+ x1_ = (x1[i] - (x0_[0] - 180)) % 360 + x0_[0] - 180
141+ p0 = Polygon(create_vertice(x0_, y0[i]))
142+ p1 = Polygon(create_vertice(x1_, y1[i]))
143+ cost[i] = (p0 & p1).area() / (p0 + p1).area()
144+ return cost
0 commit comments