1
1
# -*- coding: utf-8 -*-
2
2
"""
3
3
"""
4
- from numpy import empty , where
4
+ from numpy import empty , where , array
5
5
from numba import njit , prange , types as numba_types
6
+ from Polygon import Polygon
6
7
7
8
8
9
@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):
17
18
See: Algorithm 1 "Area of Triangles and Polygons"
18
19
"""
19
20
# 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
+ )
21
24
return product > 0
22
25
23
26
@@ -50,21 +53,13 @@ def winding_number_poly(x, y, xy_poly):
50
53
y_next = xy_poly [i_elt + 1 , 1 ]
51
54
if xy_poly [i_elt , 1 ] <= y :
52
55
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 ):
59
57
wn += 1
60
58
else :
61
59
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
+ ):
68
63
wn -= 1
69
64
return wn
70
65
@@ -92,3 +87,58 @@ def winding_number_grid_in_poly(x_1d, y_1d, i_x0, i_x1, x_size, i_y0, xy_poly):
92
87
if i_x1 < i_x0 :
93
88
i_x %= x_size
94
89
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