2424from uxarray .grid .intersections import (
2525 gca_gca_intersection ,
2626)
27+ from uxarray .grid .utils import _get_cartesian_face_edge_nodes
2728from uxarray .utils .computing import allclose
2829
2930POLE_POINTS_XYZ = {
@@ -1251,7 +1252,7 @@ def barycentric_coordinates_cartesian(polygon, point):
12511252 Parameters
12521253 ----------
12531254 polygon: np.array
1254- Cartesian coordinates of the polygons' nodes
1255+ Cartesian coordinates of the polygon nodes
12551256 point: np.array
12561257 Cartesian coordinates of the point.
12571258
@@ -1262,7 +1263,7 @@ def barycentric_coordinates_cartesian(polygon, point):
12621263 >>> point_xyz = np.array([0.0, 0.0, 1.0], dtype=np.float64)
12631264
12641265 Define a cartesian polygon:
1265- >>> point_xyz = np.array(
1266+ >>> polygon = np.array(
12661267 ... [[0.0, 0.0, 1.0], [1.0, 0.0, 0.0], [0.0, 0.0, -1.0]], dtype=np.float64
12671268 ... )
12681269
@@ -1272,11 +1273,13 @@ def barycentric_coordinates_cartesian(polygon, point):
12721273 Returns
12731274 -------
12741275 weights: np.ndarray
1275- Barycentric coordinates corresponding to each vertex in the polygon.
1276+ Barycentric coordinates corresponding to each vertex in the triangle.
1277+ nodes: np.ndarray
1278+ Indices of which nodes of the polygon form the triangle containing the point
12761279 """
1280+
12771281 n = len (polygon )
1278- weights = np .zeros (n )
1279- total_area = 0.0
1282+ weights = np .zeros (3 )
12801283
12811284 # Use the first vertex as a reference point to form triangles
12821285 p0 = polygon [0 ]
@@ -1285,41 +1288,64 @@ def barycentric_coordinates_cartesian(polygon, point):
12851288 # Get the two other points of the triangle
12861289 p1 , p2 = polygon [i ], polygon [i + 1 ]
12871290
1288- # Find the inside portion of the equation: p - p0 =(p1 - p0)b + (p2 - p0)c
1289- v1 , v2 = p1 - p0 , p2 - p0
1291+ # Get the faces in terms of their edges for the point_in_face check
1292+ face_edge = _get_cartesian_face_edge_nodes (
1293+ face_idx = 0 ,
1294+ face_node_connectivity = np .array ([[0 , 1 , 2 ]]),
1295+ n_edges_per_face = np .array ([3 ]),
1296+ node_x = np .array ([p0 [0 ], p1 [0 ], p2 [0 ]], dtype = np .float64 ),
1297+ node_y = np .array ([p0 [1 ], p1 [1 ], p2 [1 ]], dtype = np .float64 ),
1298+ node_z = np .array ([p0 [2 ], p1 [2 ], p2 [2 ]], dtype = np .float64 ),
1299+ )
1300+
1301+ # Check to see if the point lies within the current triangle
1302+ contains_point = point_in_face (
1303+ face_edge ,
1304+ point ,
1305+ inclusive = True ,
1306+ )
1307+
1308+ # If the point is in the current triangle, get the weights for that triangle
1309+ if contains_point :
1310+ # Find the inside portion of the equation: p - p0 =(p1 - p0)b + (p2 - p0)c
1311+ v1 , v2 = p1 - p0 , p2 - p0
1312+
1313+ # Solve the left side of the equation
1314+ vp = point - p0
12901315
1291- # Solve the left side of the equation
1292- vp = point - p0
1316+ # Find the largest coordinate, we will ignore this one and use the other two
1317+ abs_det = np .abs (np .cross (v1 , v2 ))
1318+ max_coord = np .argmax (abs_det )
12931319
1294- # Find the largest coordinate, we will ignore this one and use the other two
1295- abs_det = np .abs (np .cross (v1 , v2 ))
1296- max_coord = np .argmax (abs_det )
1320+ # Select the two coordinates to find corresponding weights for
1321+ idx = [j for j in range (3 ) if j != max_coord ]
1322+ array = np .array ([v1 [idx [0 ]], v1 [idx [1 ]]])
1323+ array2 = np .array ([v2 [idx [0 ]], v2 [idx [1 ]]])
12971324
1298- # Select the two coordinates to find corresponding weights for
1299- idx = [j for j in range (3 ) if j != max_coord ]
1300- array = np .array ([v1 [idx [0 ]], v1 [idx [1 ]]])
1301- array2 = np .array ([v2 [idx [0 ]], v2 [idx [1 ]]])
1325+ A = np .column_stack ((array , array2 )) # 2x2 matrix
1326+ b = np .array ([vp [idx [0 ]], vp [idx [1 ]]]) # Right-hand side vector
13021327
1303- A = np . column_stack (( array , array2 )) # 2x2 matrix
1304- b = np .array ([ vp [ idx [ 0 ]], vp [ idx [ 1 ]]]) # Right-hand side vector
1328+ # Solve for weights b, c
1329+ b_c = np .linalg . solve ( A , b )
13051330
1306- # Solve for weights b, c
1307- b_c = np . linalg . solve ( A , b )
1331+ # Solve for a
1332+ a = 1 - b_c [ 0 ] - b_c [ 1 ]
13081333
1309- # Solve for a
1310- a = 1 - b_c [ 0 ] - b_c [ 1 ]
1334+ # Compute triangle area
1335+ triangle_area = 0.5 * np . linalg . norm ( np . cross ( v1 , v2 ))
13111336
1312- # Compute triangle area
1313- triangle_area = 0.5 * np .linalg .norm (np .cross (v1 , v2 ))
1314- total_area += triangle_area
1337+ # Calculate weights
1338+ weights [0 ] += a * triangle_area
1339+ weights [1 ] += b_c [0 ] * triangle_area
1340+ weights [2 ] += b_c [1 ] * triangle_area
13151341
1316- # Accumulate weights
1317- weights [0 ] += a * triangle_area
1318- weights [i ] += b_c [0 ] * triangle_area
1319- weights [i + 1 ] += b_c [1 ] * triangle_area
1342+ # Normalize weights so they sum to 1
1343+ if triangle_area > 0 :
1344+ weights /= triangle_area
13201345
1321- # Normalize weights so they sum to 1
1322- if total_area > 0 :
1323- weights /= total_area
1346+ # The nodes of the triangle, so it can be known which values to apply the weights to
1347+ nodes = np . array ([ 0 , i , i + 1 ])
1348+ return weights , nodes
13241349
1325- return weights
1350+ # If the point doesn't reside in the polygon, raise an error
1351+ raise ValueError ("Point does not reside in polygon" )
0 commit comments