9 assert polygon.ndim == 2
14 xp1, yp1 = np.roll(xp0, 1), np.roll(yp0, 1)
16 xp0, yp0 = polygon[:, :-1]
17 xp1, yp1 = polygon[:, 1:]
20 x0 = np.asarray(x0)[...,
None]
21 y0 = np.asarray(y0)[...,
None]
22 x1 = np.asarray(x1)[...,
None]
23 y1 = np.asarray(y1)[...,
None]
35 denom = dx1 * dy2 - dy1 * dx2
36 denominatorScale = dx2**2 + dy2**2 + dx1**2 + dy1**2
39 parallel = np.isclose(denom, 0, atol=denominatorScale * 1e-8)
40 denom[parallel] = 1e300
46 t = (dx0 * dy2 - dy0 * dx2) / denom
47 u = (dx0 * dy1 - dy0 * dx1) / denom
50 intersects = (~parallel) & (t >= 0) & (t <= 1) & (u >= 0) & (u <= 1)
53 any_intersect = np.any(intersects, axis=-1)
61 assert polygon.ndim == 2
64 xp1, yp1 = np.roll(xp0, 1), np.roll(yp0, 1)
66 xp0, yp0 = polygon[:, :-1]
67 xp1, yp1 = polygon[:, 1:]
69 x = np.asarray(x)[...,
None]
70 y = np.asarray(y)[...,
None]
73 x0, y0 = xp0 - x, yp0 - y
74 x1, y1 = xp1 - x, yp1 - y
77 cross = x0 * y1 - x1 * y0
78 dot = x0 * x1 + y0 * y1
79 angles = np.arctan2(cross, dot)
81 on_some_edge = np.isclose(np.abs(angles), np.pi, rtol=1e-9).any(axis=-1)
84 winding_number = np.sum(angles, axis=-1)
87 return (np.abs(winding_number) > 1e-8) | on_some_edge
91 origin: np.ndarray, h: float, ijks: np.ndarray, elem: np.ndarray, closed=
True
97 ijks: (2, ...) integer array
98 elem: is a 2D polygon, 2D coords of shape (2+, n_point)
100 assert elem.ndim == 2
101 n_point = elem.shape[1]
102 originCS = np.ones(ijks.ndim, dtype=np.int64)
104 ll = origin.reshape(originCS) + ijks.astype(np.float64) * h
105 ru = origin.reshape(originCS) + (ijks.astype(np.float64) + 1) * h
107 cshapeB = np.array(ru.shape, dtype=np.int64)
109 eshapeB = np.ones(ijks.ndim, dtype=np.int64)
114 elemXViewB = elem[0].reshape(eshapeB)
115 elemYViewB = elem[1].reshape(eshapeB)
117 xMaxViewB = ru[0].reshape(cshapeB)
118 xMinViewB = ll[0].reshape(cshapeB)
119 yMaxViewB = ru[1].reshape(cshapeB)
120 yMinViewB = ll[1].reshape(cshapeB)
122 any_e_node_in_box = (
123 (elemXViewB <= xMaxViewB)
124 & (elemXViewB >= xMinViewB)
125 & (elemYViewB <= yMaxViewB)
126 & (elemYViewB >= yMinViewB)
129 any_b_node_in_elem = (
136 any_b_edge_v_elem_edge = (
144 return any_b_node_in_elem | any_e_node_in_box | any_b_edge_v_elem_edge
148 origin: np.ndarray, h: float, ijks: np.ndarray, elem: np.ndarray, closed=
True
154 ijks: (2, ...) integer array
155 elem: is a 2D polygon, 2D coords of shape (2+, n_point)
157 assert elem.ndim == 2
158 n_point = elem.shape[1]
159 originCS = np.ones(ijks.ndim, dtype=np.int64)
161 ll = origin.reshape(originCS) + ijks.astype(np.float64) * h
163 cshapeB = np.array(ll.shape, dtype=np.int64)
165 eshapeB = np.ones(ijks.ndim, dtype=np.int64)
172 origin: np.ndarray, h: float, elem: np.ndarray, grid_eps=1e-10
174 xyzmin = elem.min(axis=1)
175 xyzmax = elem.max(axis=1)
177 lowerijk = np.floor((xyzmin - origin) / h - grid_eps)
178 upperijk = np.ceil((xyzmax - origin) / h + grid_eps)
181 (origin + upperijk * h) + grid_eps >= xyzmax
182 ), f
"{origin}, {upperijk}, {origin + upperijk * h},\n {elem}\n, {xyzmax}"
183 assert np.all((origin + lowerijk * h) - grid_eps <= xyzmin)
185 return (np.asarray(lowerijk, dtype=np.int64), np.asarray(upperijk, dtype=np.int64))
189 origin: np.ndarray, h: float, elem: np.ndarray, closed=
True
191 """get element intersecting boxes
194 origin (np.ndarray): _description_
195 h (float): _description_
196 elem (np.ndarray): _description_
197 closed (bool, optional): _description_. Defaults to True.
200 np.ndarray: ijks of the touched cells
203 iss = np.arange(lowerijk[0], upperijk[0], dtype=np.int64)
204 jss = np.arange(lowerijk[1], upperijk[1], dtype=np.int64)
205 ism, jsm = np.meshgrid(iss, jss)
206 ijks = np.array([ism, jsm])
212 origin: np.ndarray, h: float, elem: np.ndarray, closed=
True
215 get grid point ijks inside the element
217 origin (np.ndarray): _description_
218 h (float): _description_
219 elem (np.ndarray): _description_
220 closed (bool, optional): _description_. Defaults to True.
223 np.ndarray: _description_
226 iss = np.arange(lowerijk[0], upperijk[0] + 1, dtype=np.int64)
227 jss = np.arange(lowerijk[1], upperijk[1] + 1, dtype=np.int64)
228 ism, jsm = np.meshgrid(iss, jss)
229 ijks = np.array([ism, jsm])
236 originCS = np.ones(coords.ndim, dtype=np.int64)
237 originCS[0] = coords.shape[0]
238 lowerijk = np.floor((coords - origin.reshape(originCS)) / h)
239 return np.array(lowerijk, dtype=np.int64)
244 elem_test = np.array([[0.5, 2.5, 0.5], [0.5, 0.5, 2.5]], dtype=np.float64)
245 elem_test_1 = np.array([[0.5, 2.5, 0.5], [0.5, 0.5, 0.6]], dtype=np.float64)
252 [[0, 1, 2, 3] * 4, [i // 4
for i
in range(4 * 4)]], dtype=np.int64