differt.rt.utils module#

Ray Tracing utilities.

To generate a subset of all paths between two vertices, e.g., a transmitter TX and a received RX, methods generate each path from a corresponding path candidate.

A path candidate is simply a list of primitive indices to indicate with what primitive the path interact, and in what order. The latter indicates that any permutation of a given path candidate will result in another path.

I.e., the path candidate [4, 7] indicates that the path first interacts with primitive 4, then primitive 7, while the path candidate [7, 4] indicates a path interacting first with 7 then with 4.

An empty path candidate indicates a direct path from TX or RX, also known as line of sight path.

In general, interaction can be anything of the following: reflection, diffraction, refraction, etc. The utilities present in this module do not take care of the interaction type.

You can read more about path candidates in [EOJ23].

generate_all_path_candidates(num_primitives, order)[source]#

Generate an array of all path candidates for fixed path order and a number of primitives.

The returned array contains, for each row, an array of order indices indicating the primitive with which the path interacts.

This list is generated as the list of all paths from one node to another, by passing by exactly order primitives. Calling this function is equivalent to calling itertools.product with parameters [0, 1, ..., num_primitives - 1] and repeat=order, and removing entries with containing loops, i.e., two or more consecutive indices that are equal.

Parameters:
  • num_primitives (int) – The (positive) number of primitives.

  • order (int) – The path order. An order less than one returns an empty array.

Return type:

UInt[Array, 'num_candidates order']

Returns:

An unsigned array with primitive indices on each columns. Its number of columns is actually equal to num_primitives * ((num_primitives - 1) ** (order - 1)).

generate_all_path_candidates_chunks_iter(num_primitives, order, chunk_size=1000)[source]#

Iterator variant of generate_all_path_candidates, grouped in chunks of size of max. chunk_size.

Parameters:
  • num_primitives (int) – The (positive) number of primitives.

  • order (int) – The path order.

  • chunk_size (int) – The size of each chunk.

Return type:

_SizedIterator[UInt[Array, 'chunk_size order']]

Returns:

An iterator of unsigned arrays with primitive indices.

generate_all_path_candidates_iter(num_primitives, order)[source]#

Iterator variant of generate_all_path_candidates.

Parameters:
  • num_primitives (int) – The (positive) number of primitives.

  • order (int) – The path order.

Return type:

_SizedIterator[UInt[Array, 'order']]

Returns:

An iterator of unsigned arrays with primitive indices.

rays_intersect_any_triangle(ray_origins, ray_directions, triangle_vertices, epsilon=1e-06, hit_threshold=0.999)[source]#

Return whether rays intersect any of the triangles using the Möller-Trumbore algorithm.

This function should be used when allocating an array of size *batch num_triangles 3 (or bigger) is not possible, and you are only interested in checking if at least one of the triangles is intersect.

A triangle is considered to be intersected if t < hit_threshold & hit evaluates to True.

Parameters:
  • ray_origins (Float[Array, '*batch 3']) – An array of origin vertices.

  • ray_directions (Float[Array, '*batch 3']) – An array of ray direction. The ray ends should be equal to ray_origins + ray_directions.

  • triangle_vertices (Float[Array, 'num_triangles 3 3']) – An array of triangle vertices.

  • epsilon (Union[float, Float[Array, '']]) –

    A small tolerance threshold that allows rays to hit the triangles slightly outside the actual area. A positive value virtually increases the size of the triangles, a negative value will have the opposite effect.

    Such a tolerance is especially useful when rays are hitting triangle edges, a very common case if geometries are planes split into multiple triangles.

  • hit_threshold (Union[float, Float[Array, '']]) – A threshold value below which a hit is considered to be valid. Above this threshold, the ray will only hit the triangle if prolonged. In theory, this threshold value should be equal to 1.0, but in a small tolerance must be used.

Return type:

Bool[Array, '*batch']

Returns:

For each ray, whether it intersects with any of the triangles.

rays_intersect_triangles(ray_origins, ray_directions, triangle_vertices, epsilon=1e-06)[source]#

Return whether rays intersect corresponding triangles using the Möller-Trumbore algorithm.

The current implementation closely follows the C++ code from Wikipedia.

Parameters:
  • ray_origins (Float[Array, '*batch 3']) – An array of origin vertices.

  • ray_directions (Float[Array, '*batch 3']) – An array of ray direction. The ray ends should be equal to ray_origins + ray_directions.

  • triangle_vertices (Float[Array, '*batch 3 3']) – An array of triangle vertices.

  • epsilon (Union[float, Float[Array, '']]) –

    A small tolerance threshold that allows rays to hit the triangles slightly outside the actual area. A positive value virtually increases the size of the triangles, a negative value will have the opposite effect.

    Such a tolerance is especially useful when rays are hitting triangle edges, a very common case if geometries are planes split into multiple triangles.

Return type:

tuple[Float[Array, '*batch'], Bool[Array, '*batch']]

Returns:

For each ray, return the scale factor of ray_directions for the vector to reach the corresponding triangle, and whether the intersection actually lies inside the triangle.