Skip to content

capturegraph.scheduling.distance.angle #

Angle Distance - Circular Angular Distance#

Measures distance between angles accounting for their circular nature. For example, 359° is close to 1°.

angle_degrees(sigma_deg=10.0, period=360.0) #

Create a circular angular distance function for degrees.

Measures the shortest angular distance between two angles on a circle. By default, assumes 360° period (full rotation).

Parameters:

Name Type Description Default
sigma_deg float

Normalization factor in degrees. Angles within sigma_deg apart have distance < 1.0. Default is 10°.

10.0
period float

The period of the angle in degrees. Default is 360° (full circle). Use 180° for angles that wrap at ±90° (like latitude).

360.0

Returns:

Type Description
Callable[[float, float], float]

A distance function (angle_a, angle_b) -> float.

Example
import capturegraph.scheduling as cgsh

# Azimuth angles (0-360°)
dist_fn = cgsh.distance.angle_degrees(sigma_deg=15.0)

# Use with combine
combined = cgsh.distance.combine(
    azimuth=cgsh.distance.angle_degrees(sigma_deg=10.0)
)
Source code in capturegraph-lib/capturegraph/scheduling/distance/angle.py
def angle_degrees(
    sigma_deg: float = 10.0,
    period: float = 360.0,
) -> Callable[[float, float], float]:
    """Create a circular angular distance function for degrees.

    Measures the shortest angular distance between two angles on a circle.
    By default, assumes 360° period (full rotation).

    Args:
        sigma_deg: Normalization factor in degrees. Angles within `sigma_deg`
            apart have distance < 1.0. Default is 10°.
        period: The period of the angle in degrees. Default is 360° (full circle).
            Use 180° for angles that wrap at ±90° (like latitude).

    Returns:
        A distance function `(angle_a, angle_b) -> float`.

    Example:
        ```python
        import capturegraph.scheduling as cgsh

        # Azimuth angles (0-360°)
        dist_fn = cgsh.distance.angle_degrees(sigma_deg=15.0)

        # Use with combine
        combined = cgsh.distance.combine(
            azimuth=cgsh.distance.angle_degrees(sigma_deg=10.0)
        )
        ```
    """

    def distance_fn(angle_a: float, angle_b: float) -> float:
        diff = abs(angle_a - angle_b) % period
        circular_diff = min(diff, period - diff)
        return circular_diff / sigma_deg

    return distance_fn

angle_radians(sigma_rad=np.pi / 18, period=2 * np.pi) #

Create a circular angular distance function for radians.

Measures the shortest angular distance between two angles on a circle. By default, assumes 2π period (full rotation).

Parameters:

Name Type Description Default
sigma_rad float

Normalization factor in radians. Angles within sigma_rad apart have distance < 1.0. Default is π/18 (~10°).

pi / 18
period float

The period of the angle in radians. Default is 2π (full circle).

2 * pi

Returns:

Type Description
Callable[[float, float], float]

A distance function (angle_a, angle_b) -> float.

Example
import capturegraph.scheduling as cgsh
import numpy as np

# Angles in radians
dist_fn = cgsh.distance.angle_radians(sigma_rad=np.pi/6)  # 30°
Source code in capturegraph-lib/capturegraph/scheduling/distance/angle.py
def angle_radians(
    sigma_rad: float = np.pi / 18,  # ~10 degrees
    period: float = 2 * np.pi,
) -> Callable[[float, float], float]:
    """Create a circular angular distance function for radians.

    Measures the shortest angular distance between two angles on a circle.
    By default, assumes 2π period (full rotation).

    Args:
        sigma_rad: Normalization factor in radians. Angles within `sigma_rad`
            apart have distance < 1.0. Default is π/18 (~10°).
        period: The period of the angle in radians. Default is 2π (full circle).

    Returns:
        A distance function `(angle_a, angle_b) -> float`.

    Example:
        ```python
        import capturegraph.scheduling as cgsh
        import numpy as np

        # Angles in radians
        dist_fn = cgsh.distance.angle_radians(sigma_rad=np.pi/6)  # 30°
        ```
    """

    def distance_fn(angle_a: float, angle_b: float) -> float:
        diff = abs(angle_a - angle_b) % period
        circular_diff = min(diff, period - diff)
        return circular_diff / sigma_rad

    return distance_fn