pchandler.geometry.spherical.fov
Fields of View (FoVs) and hierarchical FoV trees for spherical-coordinate spatial partitioning.
This module provides classes and methods for defining and manipulating Fields of View (FoVs) and hierarchical FoV trees. It is designed to facilitate the spatial partitioning, tiling, and merging of 3D regions based on angular constraints. The module supports flexible representation of angular units and integrates with external tools to enable hierarchical partitioning of FoVs.
Key Features:
FoV Class: - Represents rectangular angular regions in 3D space. - Supports unit conversion between radians, degrees, and gradians (gon). - Provides methods for splitting, merging, and calculating geometric properties such as aspect ratios and centers.
FoVTree Class: - Implements a hierarchical tree structure for managing FoVs. - Enables efficient spatial partitioning, depth-based querying, and merging operations. - Compatible with tile-based FoV organization for large-scale datasets.
Utility Methods: - Split a single FoV into multiple tiles or quadrants. - Convert between tuple, dictionary, or NumPy array representations of FoV boundaries. - Calculate optimal partitioning schemes for FoVs based on aspect ratios and angular extents.
Dependencies:
numpy: For numerical computations.pchandler.util: Provides utilities for angle unit conversion and numerical constants.
Usage:
Example: Create an FoV and convert it between different representations:
from pchandler.fov import FoV
# Define a field of view in degrees
fov = FoV(horizontal_min=0, horizontal_max=90, elevation_min=-30, elevation_max=30, unit="deg")
# Convert to radians
fov_rad = fov.as_tuple(unit="rad")
print("FoV in radians:", fov_rad)
# Split the FoV into a 2x2 grid
sub_fovs = fov.split(shape=(2, 2))
print("Sub-FoVs:", sub_fovs)
Example: Use a hierarchical FoV tree for spatial partitioning:
from pchandler.fov import FoV, FoVTree
# Create a base FoV
base_fov = FoV(horizontal_min=0, horizontal_max=90, elevation_min=-30, elevation_max=30, unit="deg")
# Split into tiles and build a tree
tiles = base_fov.tile(FoV(horizontal_min=0, horizontal_max=30, elevation_min=-10, elevation_max=10))
fov_tree = FoVTree.build_from_tiles(tiles)
# Query the depth of the tree
print("Tree depth:", fov_tree.depth())
Classes
A rectangular angular region (Field of View) in spherical coordinates. |
|
A hierarchical tree structure for spatial partitioning of FoVs. |
- class pchandler.geometry.spherical.fov.FoV
Bases:
BaseModelA 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
+/- pidiscontinuity (left > right indicates a wrapping FoV).- classmethod construct_without_bounds_check(*, left, right, top, bottom)
Construct a FoV without bounds check.
Enables construction of an
FoVwhose angular limits cross over the standard wraparound boundary (e.g., a horizontal FoV spanning350to10degrees).- Parameters:
left (AngleLikeT) – Left horizontal bound. May be greater than
rightto denote a wraparound region.right (AngleLikeT) – Right horizontal bound.
top (AngleLikeT) – Top vertical bound.
bottom (AngleLikeT) – Bottom vertical bound. May be less than
topfor wraparound.
- Returns:
A new
FoVconstructed viapydantic.BaseModel.model_construct(), bypassing the_check_elevationand_check_bottom_and_topmodel validators.- Return type:
Notes
This method bypasses the
_check_elevationand_check_bottom_and_topmodel validators viamodel_construct(). It exists for legitimate use cases – FoVs that cross the angular wraparound (e.g., a horizontal FoV spanning350to10degrees). 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_constructcall below is deliberate and the design is correct as-is. The method is not a security bypass –construct_without_bounds_checkis 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.
- classmethod from_angles(horizontal, vertical)
Construct a FoV from horizontal and vertical angles.
- Parameters:
horizontal (VectorT | AngleArray)
vertical (VectorT | AngleArray)
- Return type:
- property crosses_pi: bool
Check whether the FoV horizontal range crosses the
+/- piboundary.- Returns:
Trueifleft > right(wrapping FoV).- Return type:
- width()
Return the angular width (horizontal extent) of the FoV.
- Returns:
The horizontal extent (accounting for wrap at
+/- pi).- Return type:
- height()
Return the angular height (vertical extent) of the FoV.
- Returns:
The vertical extent.
- Return type:
- extent()
Return the angular extent
(width, height)of the FoV.
- classmethod from_center_with_extent(centerpoint, extent)
Build an
FoVfrom a center point and angular extent.
- union(fov2)
Return the union of this FoV with another (handles wrap at
+/- pi).
- intersect(fov2)
Return the intersection of this FoV with another, or
Noneif disjoint.
- encompasses(fov2)
Check whether
selffully surroundsfov2.
- find_points_inside(horizontal, vertical)
Return a boolean mask of the input points that fall inside the FoV.
- ratio()
Return the width-to-height ratio of the FoV.
- Returns:
width() / height().- Return type:
NonNegativeFloat
- extend_to_ratio(ratio)
Extend the FoV to match a specified width-to-height ratio.
- 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:
Notes
split((1, 1))returns[self]– the original instance is reused by identity (not value-equality). Downstream code may rely onsplits[0] is fovfor this single-tile case (e.g., FoVTree’s no-op-split short-circuit).
- equal_tiles(width, height)
Divides a region into equal tiles based on a specified width and height.
- 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.
- 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
- classmethod merge(fovs)
Merge multiple FoVs into one that encompasses the total area covered.
- 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:
- 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:
- class pchandler.geometry.spherical.fov.FoVTree
Bases:
objectA hierarchical tree structure for spatial partitioning of FoVs.
- Parameters:
- static add_identifier(fovs, shape)
Add unique identifier(s) to each field of view (FoV) in the list.
- depth()
Return the depth of the FoVTree from the current node.
Leaf nodes have a depth of 1.
- Return type:
- to_list()
Convert tree structure into a flattened list.
- classmethod build_from_tiles(tiles, min_children=4, identifier='')
Construct a tree from a 2D grid of FoVs by recursive quad-splitting.
- is_leaf()
Check whether this FoVTree node is a leaf (has no child nodes).
- Returns:
Trueif the node has no children,Falseotherwise.- Return type:
- 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.
- __init__(identifier, node, children=<factory>)