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