differt2d.geometry module¶
Geometrical objects to be placed in a differt2d.scene.Scene.
- stack_leaves(pytrees, axis=0, is_leaf=None)[source]¶
Stacks the leaves of one or more Pytrees along a new axis.
Solution inspired from: https://github.com/google/jax/discussions/16882#discussioncomment-6638501.
- Parameters:
- Return type:
- Returns:
A new Pytree with leaves stacked along the new axis.
- Raises:
ValueError – If the all PyTrees are not of the same type.
- unstack_leaves(pytrees)[source]¶
Unstacks the leaves of a Pytree. Reciprocal of
stack_leaves.- Parameters:
pytrees – A Pytree.
- Return type:
- Returns:
A list of Pytrees, where each Pytree has the same structure as the input Pytree, but each leaf contains only one part of the original leaf.
- Raises:
ValueError – If the input is not the result of stacked PyTrees.
- segments_intersect(P1, P2, P3, P4, tol=0.005, approx=None, **kwargs)[source]¶
Checks whether two line segments intersect.
The first segment is defined by points P1-P2, and the second by points P3-P4.
If they exist, the intersection coordinates can expressed as either:
\[P = \alpha \left(P_2 - P_1 \right) + P_1,\]or,
\[P = \alpha \left(P_4 - P_3 \right) + P_3.\]For \(P\) to exist, both \(\alpha\) and \(\beta\) must be in the range \([0;1]\).
Warning
Division by zero may occur if the two segments are colinear.
- References:
“Graphics Gems III - 1st Edition”, section IV.6. Link to code.
- Parameters:
P1 (
Array, '2']) – The coordinates of the first point of the first segment.P2 (
Array, '2']) – The coordinates of the second point of the first segment.P3 (
Array, '2']) – The coordinates of the first point of the second segment.P4 (
Array, '2']) – The coordinates of the second point of the second segment.tol (
Union[Array, ''],float], default:0.005) – Relaxes the condition to \([-\texttt{tol};1+\texttt{tol}]\).approx (
Optional[bool], default:None) – Whether approximation is enabled or not.kwargs (
Any) – Keyword arguments passed toactivation.
- Return type:
Union[Array, '*batch'],Array, '*batch']]- Returns:
Whether the two segments intersect.
- Examples:
>>> from differt2d.geometry import segments_intersect >>> from differt2d.logic import sigmoid >>> import jax.numpy as jnp >>> P1 = jnp.array([+0.0, +0.0]) >>> P2 = jnp.array([+1.0, +0.0]) >>> P3 = jnp.array([+0.5, -1.0]) >>> P4 = jnp.array([+0.5, +1.0]) >>> segments_intersect(P1, P2, P3, P4, approx=True) Array(1., dtype=float32) >>> segments_intersect(P1, P2, P3, P4, approx=False) Array(True, dtype=bool) >>> segments_intersect(P1, P2, P3, P4, approx=True, function=sigmoid) Array(1., dtype=float32)
- path_length(points)[source]¶
Returns the length of the given path, with N points.
Note
Currently, some epsilon value is added to each path segment to avoid division by zero in the gradient of this function. Hopefully, this should not be perceived by the user.
- Parameters:
points (
Array, 'N 2']) – An array of points.- Return type:
Array, '']- Returns:
The path length.
- Examples:
>>> from differt2d.geometry import path_length >>> import jax.numpy as jnp >>> points = jnp.array([[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]) >>> path_length(points) # 1 + 1 + sqrt(2) Array(3.4142137, dtype=float32)
- normalize(vector)[source]¶
Normalizes a vector, and also returns its length.
- Parameters:
vector (
Array, '2']) – A vector.- Return type:
tuple[Array, '2'],Array, '']]- Returns:
The normalized vector and its length.
- Examples:
>>> from differt2d.geometry import normalize >>> import jax.numpy as jnp >>> vector = jnp.array([1.0, 1.0]) >>> normalize(vector) # [1., 1.] / sqrt(2), sqrt(2) (Array([0.70710677, 0.70710677], dtype=float32), Array(1.4142135, dtype=float32)) >>> zero = jnp.array([0.0, 0.0]) >>> normalize(zero) # Special behavior at 0. (Array([0., 0.], dtype=float32), Array(1., dtype=float32))
- closest_point(points, target)[source]¶
Returns the index of the closest point to some target, and the actual distance.
- Parameters:
points (
Array, 'N 2']) – An array of 2D points.target (
Array, '2']) – A target point.
- Return type:
tuple[Array, ''],Array, '']]- Returns:
The index of the closest point and the distance to the target.
- Examples:
>>> from differt2d.geometry import closest_point >>> import jax.numpy as jnp >>> target = jnp.array([0.6, 0.3]) >>> points = jnp.array( ... [ ... [0.0, 0.0], ... [1.0, 0.0], # This is the closest point ... [1.0, 1.0], ... [0.0, 1.0], ... ] ... ) >>> closest_point(points, target) (Array(1, dtype=int32), Array(0.49999997, dtype=float32)) >>> points[closest_point(points, target)[0]] Array([1., 0.], dtype=float32)
- class Point(xy=<factory>)[source]¶
-
A point object defined by its coordinates.
import matplotlib.pyplot as plt import jax.numpy as jnp from differt2d.geometry import Point ax = plt.gca() p1 = Point(xy=jnp.array([0., 0.])) _ = p1.plot(ax) p2 = Point(xy=jnp.array([1., 1.])) _ = p2.plot(ax, color="b", annotate="$p_2$") plt.show() # doctest: +SKIP
(
Source code,png,hires.png,pdf)
- Parameters:
xy (Float[jaxlib._jax.Array, '2'])
-
xy:
Array, '2']¶ Cartesian coordinates.
- plot(ax, *args, annotate=None, annotate_offset=(0.0, 0.0), annotate_kwargs=None, **kwargs)[source]¶
Plot this object on the given axes and returns the results.
- Parameters:
ax (
Axes) – The axes to plot on.args (
Any) – Arguments passed to the plot function.kwargs (
Any) – Keyword arguments passed to the plot function.annotate (
Optional[str], default:None) – Text to put next the the point.annotate_kwargs (
Optional[Mapping[str,Any]], default:None) – Keyword arguments passed tomatplotlib.axes.Axes.annotate.
- Return type:
- Returns:
The artist(s).
- class Vertex(xy=<factory>)[source]¶
-
A vertex for corner diffraction.
import matplotlib.pyplot as plt import jax.numpy as jnp from differt2d.geometry import Wall ax = plt.gca() wall = Wall(xys=jnp.array([[0., 0.], [1., 0.]])) _ = wall.plot(ax) for vertex in wall.get_vertices(): _ = vertex.plot(ax) plt.show() # doctest: +SKIP
(
Source code,png,hires.png,pdf)
- Parameters:
xy (Float[jaxlib._jax.Array, '2'])
- static parameters_count()[source]¶
Returns how many parameters (s, t, …) are needed to define an interaction point on this object.
Typically, this equals to one for 2D surfaces.
- Return type:
- Returns:
The number of parameters.
- parametric_to_cartesian(param_coords)[source]¶
- Return type:
Array, '2']- Parameters:
param_coords (Float[jaxlib._jax.Array, 'parameters_count'])
- cartesian_to_parametric(carte_coords)[source]¶
- Return type:
Array, 'parameters_count']- Parameters:
carte_coords (Float[jaxlib._jax.Array, '2'])
- evaluate_cartesian(ray_path)[source]¶
- Return type:
Array, '']- Parameters:
ray_path (Float[jaxlib._jax.Array, '3 2'])
- plot(ax, *args, **kwargs)[source]¶
Plot this object on the given axes and returns the results.
- Parameters:
ax (
Axes) – The axes to plot on.args (
Any) – Arguments passed to the plot function.kwargs (
Any) – Keyword arguments passed to the plot function.annotate – Text to put next the the point.
annotate_offset
annotate_kwargs – Keyword arguments passed to
matplotlib.axes.Axes.annotate.
- Return type:
- Returns:
The artist(s).
- class Ray(xys=<factory>)[source]¶
Bases:
ModuleA ray object with origin and destination points.
import matplotlib.pyplot as plt import jax.numpy as jnp from differt2d.geometry import Ray ax = plt.gca() ray = Ray(xys=jnp.array([[0., 0.], [1., 1.]])) _ = ray.plot(ax) plt.show() # doctest: +SKIP
(
Source code,png,hires.png,pdf)
- Parameters:
xys (Float[jaxlib._jax.Array, '2 2'])
-
xys:
Array, '2 2']¶ Cartesian coordinates (origin, dest).
- dest()[source]¶
Returns the destination of this object.
- Return type:
Array, '2']- Returns:
The destination.
- t()[source]¶
Returns the direction vector of this object.
- Return type:
Array, '2']- Returns:
The direction vector.
- rotate(angle, around=None)[source]¶
Returns a rotated copy of this ray.
- Parameters:
- Return type:
Self- Returns:
The rotated copy of this ray.
- Examples:
>>> from differt2d.geometry import Ray >>> import jax.numpy as jnp >>> ray = Ray(xys=jnp.array([[0.0, 0.0], [1.0, 0.0]])) >>> ray.rotate(angle=jnp.pi).xys Array([[ 8.742278e-08, 0.000000e+00], [-1.000000e+00, 0.000000e+00]], dtype=float32)
- class Wall(xys=<factory>)[source]¶
-
A wall object defined by its corners.
import matplotlib.pyplot as plt import jax.numpy as jnp from differt2d.geometry import Wall ax = plt.gca() wall = Wall(xys=jnp.array([[0., 0.], [1., 0.]])) _ = wall.plot(ax) plt.show() # doctest: +SKIP
(
Source code,png,hires.png,pdf)
- Parameters:
xys (Float[jaxlib._jax.Array, '2 2'])
- normal()[source]¶
Returns the normal to the current wall, expressed in cartesian coordinates and normalized.
- Return type:
Array, '2']- Returns:
The normal.
- static parameters_count()[source]¶
Returns how many parameters (s, t, …) are needed to define an interaction point on this object.
Typically, this equals to one for 2D surfaces.
- Return type:
- Returns:
The number of parameters.
- parametric_to_cartesian(param_coords)[source]¶
- Return type:
Array, '2']- Parameters:
param_coords (Float[jaxlib._jax.Array, 'parameters_count'])
- cartesian_to_parametric(carte_coords)[source]¶
- Return type:
Array, 'parameters_count']- Parameters:
carte_coords (Float[jaxlib._jax.Array, '2'])
- evaluate_cartesian(ray_path)[source]¶
- Return type:
Array, '']- Parameters:
ray_path (Float[jaxlib._jax.Array, '3 2'])
- image_of(point)[source]¶
Returns the image of a point with respect to this mirror (wall), using specular reflection.
- Parameters:
point (
Array, '2']) – The starting point.- Return type:
Array, '2']- Returns:
The image of the point.
- Examples:
>>> from differt2d.geometry import Wall >>> import jax.numpy as jnp >>> wall = Wall(xys=jnp.array([[0.0, 0.0], [1.0, 0.0]])) >>> wall.image_of(jnp.array([0.0, 1.0])) Array([ 0., -1.], dtype=float32)
- class RIS(xys=<factory>, phi=<factory>)[source]¶
Bases:
WallA very basic Reflective Intelligent Surface (RIS) object.
Here, we model a RIS such that the angle of reflection is constant with respect to its normal, regardless of the incident vector.
- Parameters:
xys (Float[jaxlib._jax.Array, '2 2'])
phi (Float[jaxlib._jax.Array, ''])
-
phi:
Array, '']¶ The constant angle of reflection.
- class Path(xys, loss=<factory>)[source]¶
-
A path object with at least two points.
import matplotlib.pyplot as plt import jax.numpy as jnp from differt2d.geometry import Path ax = plt.gca() path = Path(xys=jnp.array([[0., 0.], [.8, .2], [1., 1.]])) _ = path.plot(ax) plt.show() # doctest: +SKIP
(
Source code,png,hires.png,pdf)
- Parameters:
xys (Float[jaxlib._jax.Array, 'num_points 2'])
loss (Float[jaxlib._jax.Array, ''])
-
xys:
Array, 'num_points 2']¶ Array of cartesian coordinates.
-
loss:
Array, '']¶ The loss value for the given path.
- from_tx_objects_rx(*args, **kwargs) = Partial( func=_JitWrapper( fn='Path.from_tx_objects_rx', filter_warning=False, donate_first=False, donate_rest=False ), args=(differt2d.geometry.Path,), keywords={} )¶
- length()[source]¶
Returns the length of this path.
- Return type:
Array, '']- Returns:
The path length.
- on_objects(objects, approx=None, **kwargs)[source]¶
Returns whether the path correctly passes on the objects.
For each object i, it will check whether it contains the ith point in the path (start and end points are ignored).
- Parameters:
objects (
Sequence[Interactable]) – The list of objects to check against.approx (
Optional[bool], default:None) – Whether approximation is enabled or not.kwargs – Keyword arguments passed to
activation.
- Return type:
Union[Array, '*batch'],Array, '*batch']]- Returns:
Whether this path passes on the objects.
- intersects_with_objects(objects, path_candidate, patch=0.0, approx=None, **kwargs)[source]¶
Returns whether the path intersects with any of the objects.
The
path_candidateargument is used to avoid checking for intersection on objects the path is allowed to pass on.- Parameters:
objects (
Sequence[Interactable]) – The list of objects in the scene.path_candidate (
Array) – The object indices on which the path should pass.patch (
Union[Array, ''],float], default:0.0) – The patch value for intersection check, seeInteractable.intersects_cartesian.approx (
Optional[bool], default:None) – Whether approximation is enabled or not.kwargs (
Any) – Keyword arguments passed toactivation.
- Return type:
Union[Array, '*batch'],Array, '*batch']]- Returns:
Whether this path intersects any of the objects.
- is_valid(objects, path_candidate, interacting_objects, tol=0.01, patch=0.0, approx=None, **kwargs)[source]¶
Returns whether the current path is valid, according to three requirements (see below).
The requirements are:
the path loss is below some tolerance;
the coordinate points are correctly placed inside the corresponding interacting objects;
and the path does not intersect with any of the objects in the scene (except those concerned by 2.).
- Parameters:
objects (
Sequence[Interactable]) – The objects in the scene.path_candidate (
Array, 'order']) – The array of indices of interacting objects, usually generated withScene.all_path_candidatesinteracting_objects (
Sequence[Interactable]) – The list of interacting objects, usually obtained by callingScene.get_interacting_objects.tol (
Union[Array, ''],float], default:0.01) – The maximum allowed value for the path loss before it is considered invalid. I.e., a path loss greater thantolwill make this path invalid.patch (
Union[Array, ''],float], default:0.0) – The patch value for intersection check, seeInteractable.intersects_cartesian.approx (
Optional[bool], default:None) – Whether approximation is enabled or not.kwargs (
Any) – Keyword arguments passed toactivation.
- Return type:
Union[Array, '*batch'],Array, '*batch']]- Returns:
Whether this path is valid.
- class ImagePath(xys, loss=<factory>)[source]¶
Bases:
PathA path object that was obtained with the Image method.
- Parameters:
xys (Float[jaxlib._jax.Array, 'num_points 2'])
loss (Float[jaxlib._jax.Array, ''])
- class FermatPath(xys, loss=<factory>)[source]¶
Bases:
PathA path object that was obtained with the Fermat’s Principle Tracing method.
- Parameters:
xys (Float[jaxlib._jax.Array, 'num_points 2'])
loss (Float[jaxlib._jax.Array, ''])