pchandler.geometry.spherical

Spherical-geometry classes and helpers (Angle units, field-of-view tiles).

class pchandler.geometry.spherical.Angle

Bases: AngleBase

Represent a scalar (or, via __new__ dispatch, array) angle in any supported unit.

Supports flexible construction from numbers, strings ("45deg", "0.5 rad", "200.4gon"), and array-like inputs. Array inputs are upcast to AngleArray.

Parameters:
  • value (float) – The numerical representation of the angle.

  • unit (AngleUnit) – The unit of the angle, such as radians or degrees.

static __new__(cls, value, unit=AngleUnit.RAD)

Return a new Angle or AngleArray based on the input shape.

Parameters:
  • value (float, Array_Float_T, or str) – The angle value(s). If a string, it is parsed to create an instance.

  • unit (AngleUnit, default=AngleUnit.RAD) – The unit of the angle value(s).

Returns:

An instance of either Angle or AngleArray depending on the dimension of the input value.

Return type:

Angle or AngleArray

classmethod parse(value)

Build an Angle / AngleArray from a variety of input formats.

Supported formats include:

  • Angle | AngleArray

  • (value, unit) tuple

  • single string "45deg", "0.5 rad", "200.4gon", etc.

  • numpy scalar

  • int | float

  • numpy array

  • list | tuple of numbers

Parameters:

value (Any) – Input value to parse into an angle.

Returns:

The parsed angle.

Return type:

Angle | AngleArray

Raises:

ValueError – If value cannot be parsed as an angle.

class pchandler.geometry.spherical.AngleArray

Bases: AngleBase

Multi-dimensional array of angles, supporting indexing, iteration and unit conversion.

Parameters:
  • arr (ArrayT) – The array of angle values.

  • unit (AngleUnit, default=AngleUnit.RAD) – The unit in which arr is supplied (also the initial display unit).

static __new__(cls, arr, unit=AngleUnit.RAD)

Return a new AngleArray carrying arr (a copy as float64).

property shape: tuple[int, ...]

Return the shape of the underlying array.

Returns:

Shape tuple, matching numpy.ndarray.shape.

Return type:

tuple[int, …]

class pchandler.geometry.spherical.FoV

Bases: BaseModel

A rectangular angular region (Field of View) in spherical coordinates.

Defined by left/right horizontal bounds and top/bottom vertical bounds. Horizontal angles wrap on the +/- pi discontinuity (left > right indicates a wrapping FoV).

__init__(*, left, top, right, bottom)

Build an FoV from four angular limits.

Parameters:
  • left (Angle) – Hz ∈ [–π, +π].

  • right (Angle) – Hz ∈ [–π, +π].

  • top (Angle) – V ∈ [0, +π].

  • bottom (Angle) – V ∈ [0, +π].

center()

Return the center of the FoV.

Return type:

tuple[Angle, Angle]

classmethod construct_without_bounds_check(*, left, right, top, bottom)

Construct a FoV without bounds check.

Enables construction of an FoV whose angular limits cross over the standard wraparound boundary (e.g., a horizontal FoV spanning 350 to 10 degrees).

Parameters:
  • left (AngleLikeT) – Left horizontal bound. May be greater than right to denote a wraparound region.

  • right (AngleLikeT) – Right horizontal bound.

  • top (AngleLikeT) – Top vertical bound.

  • bottom (AngleLikeT) – Bottom vertical bound. May be less than top for wraparound.

Returns:

A new FoV constructed via pydantic.BaseModel.model_construct(), bypassing the _check_elevation and _check_bottom_and_top model validators.

Return type:

FoV

Notes

This method bypasses the _check_elevation and _check_bottom_and_top model validators via model_construct(). It exists for legitimate use cases – FoVs that cross the angular wraparound (e.g., a horizontal FoV spanning 350 to 10 degrees). The caller is responsible for ensuring the (left, right, top, bottom) quadruple represents a meaningful angular region; downstream FoV operations may produce surprising results if the invariant is violated.

This is FRAG-06 documentation (Plan 02-06 / D-22): the model_construct call below is deliberate and the design is correct as-is. The method is not a security bypass – construct_without_bounds_check is callable only by code that already has full control over the FoV construction, and the validators it skips are domain-shape checks (angular ordering), not security-shape checks.

property crosses_pi: bool

Check whether the FoV horizontal range crosses the +/- pi boundary.

Returns:

True if left > right (wrapping FoV).

Return type:

bool

property elevation_max: Angle

Elevation maximum angle value. Equivalent to the bottom attribute.

Warning

DeprecationWarning

This property is deprecated. Use the ‘bottom’ property instead.

Return type:

Angle

property elevation_min: Angle

Elevation minimum angle value. Equivalent to the top attribute.

Warning

DeprecationWarning

This property is deprecated. Use the ‘top’ property instead.

Return type:

Angle

encompasses(fov2)

Check whether self fully surrounds fov2.

Parameters:

fov2 (FoV) – Candidate inner FoV.

Returns:

True if fov2 is fully contained inside self (within EPS tolerance).

Return type:

bool

equal_tiles(width, height)

Divides a region into equal tiles based on a specified width and height.

Parameters:
Return type:

list[FoV]

extend_to_ratio(ratio)

Extend the FoV to match a specified width-to-height ratio.

Parameters:

ratio (float) – Target width-to-height ratio.

Returns:

New FoV matching the requested ratio (or self if already at ratio).

Return type:

FoV

extent()

Return the angular extent (width, height) of the FoV.

Returns:

(width, height) pair.

Return type:

tuple[Angle, Angle]

find_points_inside(horizontal, vertical)

Return a boolean mask of the input points that fall inside the FoV.

classmethod from_angles(horizontal, vertical)

Construct a FoV from horizontal and vertical angles.

Parameters:
Return type:

FoV

classmethod from_center_with_extent(centerpoint, extent)

Build an FoV from a center point and angular extent.

Parameters:
  • centerpoint (tuple[float, float]) – (horizontal_center, vertical_center) for the FoV.

  • extent (tuple[float, float]) – (width, height) extent for the FoV.

Returns:

FoV centered on centerpoint with the requested extent.

Return type:

FoV

height()

Return the angular height (vertical extent) of the FoV.

Returns:

The vertical extent.

Return type:

Angle

property horizontal_max: Angle

Horizontal maximum angle value. Equivalent to the right attribute.

Warning

DeprecationWarning

This property is deprecated. Use the ‘right’ property instead.

Return type:

Angle

property horizontal_min: Angle

Horizontal minimum angle value. Equivalent to the left attribute.

Warning

DeprecationWarning

This property is deprecated. Use the ‘left’ property instead.

Return type:

Angle

intersect(fov2)

Return the intersection of this FoV with another, or None if disjoint.

Parameters:

fov2 (FoV) – The other FoV to intersect with.

Returns:

The intersection FoV, or None if the two are disjoint.

Return type:

FoV or None

classmethod merge(fovs)

Merge multiple FoVs into one that encompasses the total area covered.

Parameters:

fovs (Iterable[FoV]) – All FoV objects to be merged.

Returns:

Smallest FoV containing all inputs.

Return type:

FoV

quadrants()

Split the FoV into four equal quadrants.

Returns:

The four quadrant FoVs (top-left, top-right, bottom-left, bottom-right).

Return type:

tuple of Self

ratio()

Return the width-to-height ratio of the FoV.

Returns:

width() / height().

Return type:

NonNegativeFloat

split(shape)

Split the FoV into smaller FoVs based on a grid shape.

Parameters:

shape (tuple[int, int]) – The number of horizontal and vertical splits respectively.

Return type:

list[FoV]

Notes

split((1, 1)) returns [self] – the original instance is reused by identity (not value-equality). Downstream code may rely on splits[0] is fov for this single-tile case (e.g., FoVTree’s no-op-split short-circuit).

tile(target_extent, expand_to_integer_multiple=False)

Divides the current field of view (FOV) into smaller tiles based on the specified target extent/FoV.

If expand_to_integer_multiple is True, the method ensures that the field of view is expanded to the nearest integer multiple of the target_extent dimensions before tiling.

Parameters:
  • target_extent (FoV) – FoV object representing the target extent for tiling.

  • expand_to_integer_multiple (bool, optional)

Return type:

list[list[FoV]]

union(fov2)

Return the union of this FoV with another (handles wrap at +/- pi).

Parameters:

fov2 (FoV) – The other FoV to union with.

Returns:

The smallest FoV containing both inputs.

Return type:

FoV

width()

Return the angular width (horizontal extent) of the FoV.

Returns:

The horizontal extent (accounting for wrap at +/- pi).

Return type:

Angle

left: Angle
right: Angle
top: Angle
bottom: Angle
class pchandler.geometry.spherical.FoVTree

Bases: object

A hierarchical tree structure for spatial partitioning of FoVs.

Parameters:
  • identifier (str) – Unique identifier for this tree node.

  • node (FoV) – The FoV associated with this tree node.

  • children (dict[str, FoVTree] | None) – Dictionary of child nodes, if any.

__init__(identifier, node, children=<factory>)
static add_identifier(fovs, shape)

Add unique identifier(s) to each field of view (FoV) in the list.

Parameters:
  • fovs (list[FoV])

  • shape (tuple[int, int]) – Shape dimensions used to calculate the identifier length.

Returns:

A tuple containing tuples, each consisting of a unique identifier and the corresponding FoV object.

Return type:

tuple[tuple[str | Any, FoV], …]

classmethod build_from_tiles(tiles, min_children=4, identifier='')

Construct a tree from a 2D grid of FoVs by recursive quad-splitting.

Parameters:
  • tiles (list[list[FoV]]) – Grid of FoVs.

  • min_children (int, default=4) – The minimum number of children to avoid further splitting.

  • identifier (str, default="") – Unique identifier for this node.

Returns:

Root of the constructed tree, or None if tiles is empty.

Return type:

FoVTree

static calculate_optimal_shape(fov, target_ratio, max_denominator)

Calculate the optimal shape based on a given field of view (FoV), target ratio, and maximum denominator.

Parameters:
  • fov (FoV)

  • target_ratio (float)

  • max_denominator (float) – Maximum number of FoV tree should be split into along a direction

Return type:

tuple[int, int]

depth()

Return the depth of the FoVTree from the current node.

Leaf nodes have a depth of 1.

Return type:

int

is_leaf()

Check whether this FoVTree node is a leaf (has no child nodes).

Returns:

True if the node has no children, False otherwise.

Return type:

bool

to_list()

Convert tree structure into a flattened list.

Returns:

Each tuple consists of the identifier and the FoV node

Return type:

list[(str, FoV)]

identifier: str
node: FoV
children: dict[str, Self] | None

Modules

angle

Unit-aware angle scalar and array wrappers (radians / degrees / gon).

fov

Fields of View (FoVs) and hierarchical FoV trees for spherical-coordinate spatial partitioning.