Helper Functions#

KDTree queries, edge/face utilities for spherical meshes.

sphedron.helpers.faces_to_edges(faces: ndarray[tuple[Any, ...], dtype[_ScalarT]]) ndarray[tuple[Any, ...], dtype[_ScalarT]][source]#

Convert faces to an array of composing edges.

Each face is defined by K node indices. This function returns all edges by pairing each node index with its successor in the face, wrapping around to the first node at the end.

Parameters:

faces (numpy.ndarray[M, K]) – Array of faces, shape (M, K), where each row lists K node indices defining a single face.

Returns:

Array of edges with shape (M*K, 2), where each row is a pair of node indices forming an edge.

Return type:

numpy.ndarray[N, 2]

Example

>>> import numpy as np
>>> faces = np.array([[0, 1, 2], [2, 3, 0]])
>>> edges = faces_to_edges(faces)
>>> edges
array([[0, 1],
       [1, 2],
       [2, 0],
       [2, 3],
       [3, 0],
       [0, 2]])
sphedron.helpers.query_nearest(references_xyz: ndarray[tuple[Any, ...], dtype[_ScalarT]], nodes_xyz: ndarray[tuple[Any, ...], dtype[_ScalarT]], n_neighbors: int) Tuple[ndarray[tuple[Any, ...], dtype[_ScalarT]], ndarray[tuple[Any, ...], dtype[_ScalarT]]][source]#

Find the nearest neighbors for each query point among reference points.

Parameters:
  • references_xyz (numpy.ndarray[N, 3]) – Reference points in 3D space.

  • nodes_xyz (numpy.ndarray[M, 3]) – Query points in 3D space.

  • n_neighbors (int) – Number of nearest neighbors to return.

Returns:

A pair (distances, indices) where distances[i, j] is the distance from nodes_xyz[i] to its j-th nearest neighbor among references_xyz, and indices[i, j] is the index of that neighbor.

Return type:

Tuple[numpy.ndarray[M, n_neighbors], numpy.ndarray[M, n_neighbors]]

Example

>>> import numpy as np
>>> refs = np.random.rand(10, 3)
>>> nodes = np.random.rand(5, 3)
>>> dists, idxs = query_nearest(refs, nodes, n_neighbors=3)
sphedron.helpers.query_radius(references_xyz: ndarray[tuple[Any, ...], dtype[_ScalarT]], nodes_xyz: ndarray[tuple[Any, ...], dtype[_ScalarT]], radius: float) ndarray[tuple[Any, ...], dtype[_ScalarT]][source]#

Find all neighbors within a given radius for each query point.

Parameters:
  • references_xyz (numpy.ndarray[N, 3]) – Reference points in 3D space.

  • nodes_xyz (numpy.ndarray[M, 3]) – Query points in 3D space.

  • radius (float) – Radius within which to search for neighbors.

Returns:

A list of length M; each entry is an array of indices of references_xyz that lie within radius of the corresponding nodes_xyz point.

Return type:

List[numpy.ndarray]

Example

>>> import numpy as np
>>> refs = np.random.rand(10, 3)
>>> nodes = np.random.rand(5, 3)
>>> neighbors = query_radius(refs, nodes, radius=0.2)
sphedron.helpers.form_edges(sender_groups: ndarray[tuple[Any, ...], dtype[_ScalarT]], receiver_indices: ndarray[tuple[Any, ...], dtype[_ScalarT]] | List) ndarray[tuple[Any, ...], dtype[_ScalarT]][source]#

Connect sender nodes to receiver nodes and return the edge list.

Parameters:
  • sender_groups (numpy.ndarray or list) – 1D or 2D array of sender node indices. Each entry can be a scalar or a list of indices.

  • receiver_indices (numpy.ndarray or list) – 1D array of receiver node indices, same length as sender_groups.

Returns:

Array of edges where each row is (sender_index, receiver_index).

Return type:

numpy.ndarray[N, 2]

Example

>>> senders = [[0, 1], 2]
>>> receivers = [3, 4]
>>> edges = form_edges(senders, receivers)
>>> print(edges)
[[0, 3], [1, 3], [2, 4]]
sphedron.helpers.get_rotation_matrices(references_thetaphi: ndarray[tuple[Any, ...], dtype[_ScalarT]], zero_latitude: bool, zero_longitude: bool)[source]#

Compute rotation matrices to align spherical coords to zero lat/long.

Parameters:
  • references_thetaphi (numpy.ndarray[N, 2]) – Array of (theta, phi) angles in radians.

  • zero_latitude (bool) – If True, rotate so that theta → 0.

  • zero_longitude (bool) – If True, rotate so that phi → 0.

Returns:

Rotation matrix for each reference angle, suitable for Rotation.from_euler(…).as_matrix().

Return type:

numpy.ndarray[N, 3, 3]

Raises:

ValueError – If neither zero_latitude nor zero_longitude is enabled.

Example

>>> import numpy as np
>>> thph = np.array([[np.pi/4, np.pi/2]])
>>> mats = get_rotation_matrices(thph, True, False)
>>> mats.shape
(1, 3, 3)
sphedron.helpers.compute_angles_per_depth(max_depth: int = 100) ndarray[tuple[Any, ...], dtype[_ScalarT]][source]#

Compute angular separation between nodes as depth increases.

Parameters:

max_depth (int) – Number of depth steps to compute (>=1).

Returns:

Array of angles in degrees for each depth.

Return type:

numpy.ndarray[max_depth]

Example

>>> angles = compute_angles_per_depth(5)
>>> len(angles)
5
sphedron.helpers.compute_edges_lenghts(nodes: ndarray[tuple[Any, ...], dtype[_ScalarT]], edges: ndarray[tuple[Any, ...], dtype[_ScalarT]]) ndarray[tuple[Any, ...], dtype[_ScalarT]][source]#

Compute the lengths of edges given node coordinates.

Parameters:
  • nodes (numpy.ndarray[K, 3]) – Array of node coordinates.

  • edges (numpy.ndarray[E, 2]) – Array of edges as index pairs.

Returns:

Euclidean lengths of each edge.

Return type:

numpy.ndarray[E]

Example

>>> import numpy as np
>>> nodes = np.array([[0, 0, 0], [1, 0, 0]])
>>> edges = np.array([[0, 1]])
>>> lengths = compute_edges_lenghts(nodes, edges)
>>> lengths
array([1.])
sphedron.helpers.compute_edges_angles(nodes: ndarray[tuple[Any, ...], dtype[_ScalarT]], faces: ndarray[tuple[Any, ...], dtype[_ScalarT]]) ndarray[tuple[Any, ...], dtype[_ScalarT]][source]#

Calculate node‐to‐node angles from edge lengths.

Parameters:
  • nodes (numpy.ndarray[K, 3]) – Coordinates of nodes.

  • faces (numpy.ndarray[M, 2]) – Array defining edges as pairs of indices.

Returns:

Angles in degrees for each edge.

Return type:

numpy.ndarray[M]

Example

>>> import numpy as np
>>> nodes = np.array([[0, 0, 1], [0, 1, 0]])
>>> faces = np.array([[0, 1]])
>>> angles = compute_edges_angles(nodes, faces)
>>> angles
array([90.])