differt.geometry.fermat_path_on_planar_mirrors

differt.geometry.fermat_path_on_planar_mirrors#

fermat_path_on_planar_mirrors(from_vertex, to_vertex, mirror_vertices, mirror_normals, **kwargs)[source]#

Return the ray path between a pair of vertices, that reflects on a given list of mirrors in between.

Parameters:
  • from_vertex (Float[ArrayLike, '*#batch 3']) – from vertex, i.e., vertex from which the ray path starts. In a radio communications context, this is usually the transmitter position.

  • to_vertex (Float[ArrayLike, '*#batch 3']) – to vertex, i.e., vertex to which the ray path ends. In a radio communications context, this is usually the receiver position.

  • mirror_vertices (Float[ArrayLike, '*#batch num_mirrors 3']) – Mirror vertices. For each mirror, any vertex on the infinite plane that describes the mirror is considered to be a valid vertex.

  • mirror_normals (Float[ArrayLike, '*#batch num_mirrors 3']) –

    Mirror normals, where each normal has a unit length and is perpendicular to the corresponding mirror.

    Note

    Unlike with the Image method, the normals do not actually have to be unit vectors. However, we keep the same documentation so it is easier for the user to move from one method to the other.

  • kwargs (Any) – Keyword arguments passed to fermat_path_on_linear_objects.

Return type:

Float[Array, '*batch num_mirrors 3']

Returns:

Intermediate ray path vertices obtained using Fermat’s principle.

Note

The paths do not contain the starting and ending vertices.

You can easily create the complete ray paths using assemble_path:

path = fermat_path_on_planar_mirrors(...)

full_path = assemble_path(
    from_vertex,
    path,
    to_vertex,
)

Examples

The following example is the same as for the image_method, but using the Fermat principle.

>>> from differt.geometry import Mesh, normalize, assemble_path
>>> from differt.plotting import draw_markers, draw_paths, reuse
>>> from differt.rt import fermat_path_on_planar_mirrors
>>>
>>> from_vertex = jnp.array([+2.0, -1.0, +0.0])
>>> to_vertex = jnp.array([+2.0, +4.0, +0.0])
>>> mirror_vertices = jnp.array([
...     [3.0, 3.0, 0.0],
...     [4.0, 3.4, 0.0],
... ])
>>> mirror_normals = jnp.array([
...     [+1.0, -1.0, +0.0],
...     [-1.0, +0.0, +0.0],
... ])
>>> mirror_normals, _ = normalize(mirror_normals)
>>> path = fermat_path_on_planar_mirrors(
...     from_vertex,
...     to_vertex,
...     mirror_vertices,
...     mirror_normals,
... )
>>> with reuse(backend="plotly") as fig:
...     Mesh.plane(
...         mirror_vertices[0], normal=mirror_normals[0], rotate=-0.954
...     ).plot(color="red")
...     Mesh.plane(mirror_vertices[1], normal=mirror_normals[1]).plot(
...         color="red"
...     )
...
...     full_path = assemble_path(
...         from_vertex,
...         path,
...         to_vertex,
...     )
...     draw_paths(full_path, marker={"color": "green"}, name="Final path")
...     markers = jnp.vstack((from_vertex, to_vertex))
...     draw_markers(
...         markers,
...         labels=["BS", "UE"],
...         marker={"color": "black"},
...         name="BS/UE",
...     )
...     fig.update_layout(scene_aspectmode="data")
>>> fig