Steiner Ellipse Module

This module allows to find the smallest ellipse englobing three points using the Steiner algorithm [Wikipedia, 2025]. The module also contains useful functions allowing to find the bounding box (BBOX) of an ellipse and determine whether points are inside an ellipse using its matrix definition.

qdecomp.utils.steiner_ellipse.assert_steiner_ellipse(p1: ndarray, p2: ndarray, p3: ndarray) None[source]

Check if the three given points can be used to define a Steiner ellipse. The three points must be distinct and non-collinear to define a valid ellipse. If the points are not valid, a ValueError is raised.

Parameters:
  • p1 (list[float]) – First point

  • p2 (list[float]) – Second point

  • p3 (list[float]) – Third point

Raises:
  • ValueError – If at least two of the points are the same

  • ValueError – If the three points are collinear

qdecomp.utils.steiner_ellipse.steiner_ellipse_def(p1: list[float], p2: list[float], p3: list[float]) tuple[ndarray, ndarray][source]

Calculates the smallest ellipse that passes through the three given points using the Steiner method. The ellipse is represented by the equation \((u − p)^\dagger D (u − p) \leq 1\), where \(p\) is the center of the ellipse and \(D\) is a matrix that defines its shape and orientation. \(p1\), \(p2\), \(p3\) can be any iterable containing real numbers.

Parameters:
  • p1 (list[float]) – First point

  • p2 (list[float]) – Second point

  • p3 (list[float]) – Third point

Returns:

\((D, p)\): the matrix defining the shape and orientation of the ellipse, and the center of the ellipse

Return type:

tuple[np.ndarray, np.ndarray]

qdecomp.utils.steiner_ellipse.is_inside_ellipse(u: list[float] | list[list[float] | list[NestedList]], D: ndarray, p: ndarray) ndarray[source]

Check if a point u (or an array of points) is inside the ellipse defined by matrix D and center p. The function works for both single points and arrays of points, where the last dimension of u must be the same as the number of dimensions of the ellipse.

Parameters:
  • u (NestedList) – The point(s) to be tested, an array of shape (…, n_dim)

  • D (np.ndarray) – Matrix defining the ellipse’s shape and orientation

  • p (np.ndarray) – Center of the ellipse

Returns:

A boolean array indicating if each point is inside the ellipse

Return type:

np.ndarray

Raises:
  • IndexError – If the dimensions of the D and p arguments are incompatible

  • IndexError – If the last dimension of the points to test is different from the number of dimensions of the ellipse

qdecomp.utils.steiner_ellipse.ellipse_bbox(D: ndarray, p: ndarray) ndarray[source]

Find the axis-aligned bounding box (BBOX) of an ellipse. Refer to the comment made by Rodrigo de Azevedo on November 30th, 2020 in [de Azevedo, 2020].

Parameters:
  • D (np.ndarray) – Matrix defining the ellipse’s shape and orientation

  • p (np.ndarray) – Center of the ellipse

Returns:

A numpy array of shape (n_dim, 2) representing the bounding box. The first index corresponds to each spatial dimension (e.g., x, y, …), and the second index contains the minimum and maximum bounds along that dimension.

Return type:

np.ndarray

References

[dA20]

Rodrigo de Azevedo. Smallest axis-aligned bounding box of hyper-ellipsoid. November 2020. URL: https://math.stackexchange.com/questions/3926884/smallest-axis-aligned-bounding-box-of-hyper-ellipsoid.

[Wik25]

Wikipedia. Steiner ellipse. 2025. URL: https://en.wikipedia.org/wiki/Steiner_ellipse.