Skip to content

Angles

circumplex.utils.angles

Angle utilities and predefined angle sets.

This module provides tools for working with circular angles, including conversion between degrees and radians, and standard angle sets for circumplex models.

CLASS DESCRIPTION
AngleStart

Enumeration for angle starting positions.

Degree

Angular measurement in degrees.

Radian

Angular measurement in radians.

FUNCTION DESCRIPTION
octants

Get octant angles starting from a specified position.

degrees_to_radians

Convert degrees to radians.

radians_to_degrees

Convert radians to degrees.

cosine_form

Cosine function with amplitude, displacement and elevation parameters.

sort_angles

Sort angles and corresponding scores in ascending order.

ATTRIBUTE DESCRIPTION
OCTANTS

Standard octant angles in degrees.

TYPE: NDArray[Shape['8'], Float]

QUADRANTS

Standard quadrant angles in degrees.

TYPE: NDArray[Shape['4'], Float]

POLES

Standard pole angles in degrees.

TYPE: NDArray[Shape['2'], Float]

OCTANTS module-attribute

OCTANTS: NDArray[Shape['8'], Float] = array([90, 135, 180, 225, 270, 315, 360, 45], dtype=float)

Standard octant angles in degrees.

Returns the eight standard positions on a circumplex circle, spaced 45 degrees apart, starting from 90 degrees (North).

QUADRANTS module-attribute

QUADRANTS: NDArray[Shape['4'], Float] = array([90, 180, 270, 360], dtype=float)

Standard quadrant angles in degrees.

Returns the four standard quadrant positions on a circumplex circle, spaced 90 degrees apart.

POLES module-attribute

POLES: NDArray[Shape['2'], Float] = array([90, 270], dtype=float)

Standard pole angles in degrees.

Returns the two primary axis positions (vertical poles) on a circumplex circle.

AngleStart

Bases: IntEnum

Enumeration for angle starting positions.

Degree

Bases: float

Angular measurement in degrees.

A float subclass representing an angle in degrees, with conversion methods to radians.

Examples:

>>> angle = Degree(90)
>>> angle.to_radians()
Radian(1.5707963267948966)
METHOD DESCRIPTION
to_radians

Convert to radians.

__repr__

Return a compact string representation, e.g., '90°'.

to_radians

to_radians() -> 'Radian'

Convert to radians.

RETURNS DESCRIPTION
'Radian'

Angle in radians

Source code in src/circumplex/utils/angles.py
def to_radians(self) -> "Radian":
    """Convert to radians.

    Returns
    -------
    :
        Angle in radians

    """
    return Radian(np.radians(self))

__repr__

__repr__() -> str

Return a compact string representation, e.g., '90°'.

Source code in src/circumplex/utils/angles.py
def __repr__(self) -> str:
    """Return a compact string representation, e.g., '90°'."""
    return f"{float(self):.0f}°"

Radian

Bases: float

Angular measurement in radians.

A float subclass representing an angle in radians, with conversion methods to degrees.

Examples:

>>> angle = Radian(np.pi/2)
>>> angle.to_degrees()
Degree(90.0)
METHOD DESCRIPTION
to_degrees

Convert to degrees.

__repr__

Return a compact string representation, e.g., '1.571 rad'.

to_degrees

to_degrees() -> Degree

Convert to degrees.

RETURNS DESCRIPTION
Degree

Angle in degrees

Source code in src/circumplex/utils/angles.py
def to_degrees(self) -> Degree:
    """Convert to degrees.

    Returns
    -------
    :
        Angle in degrees

    """
    return Degree(np.degrees(self))

__repr__

__repr__() -> str

Return a compact string representation, e.g., '1.571 rad'.

Source code in src/circumplex/utils/angles.py
def __repr__(self) -> str:
    """Return a compact string representation, e.g., '1.571 rad'."""
    return f"{float(self):.3f} rad"

octants

octants(start: AngleStart | int = AngleStart.EAST) -> NDArray[Shape['8'], Float]

Get octant angles starting from a specified position.

PARAMETER DESCRIPTION
start

Starting position for the octants (default is 90 degrees).

TYPE: AngleStart | int DEFAULT: EAST

RETURNS DESCRIPTION
NDArray[Shape['8'], Float]

Array of octant angles in degrees starting from the specified position.

Examples:

>>> octants(AngleStart.ONE)
array([  0.,  45.,  90., 135., 180., 225., 270., 315.])
>>> octants(AngleStart.FIVE)
array([180., 225., 270., 315.,   0.,  45.,  90., 135.])
Source code in src/circumplex/utils/angles.py
def octants(start: AngleStart | int = AngleStart.EAST) -> NDArray[Shape["8"], Float]:
    """Get octant angles starting from a specified position.

    Parameters
    ----------
    start
        Starting position for the octants (default is 90 degrees).

    Returns
    -------
    :
        Array of octant angles in degrees starting from the specified position.

    Examples
    --------
    >>> octants(AngleStart.ONE)
    array([  0.,  45.,  90., 135., 180., 225., 270., 315.])
    >>> octants(AngleStart.FIVE)
    array([180., 225., 270., 315.,   0.,  45.,  90., 135.])

    """
    if isinstance(start, int):
        start = AngleStart(start)

    base_angles = np.array([0, 45, 90, 135, 180, 225, 270, 315], dtype=float)
    start_index = start
    return np.roll(base_angles, -start_index)

degrees_to_radians

degrees_to_radians(degrees: float | ndarray) -> float | np.ndarray

Convert degrees to radians.

PARAMETER DESCRIPTION
degrees

Angle(s) in degrees

TYPE: float | ndarray

RETURNS DESCRIPTION
float | ndarray

Angle(s) in radians

Examples:

>>> degrees_to_radians(180)
3.141592653589793
>>> degrees_to_radians(OCTANTS)
array([1.57..., 2.35..., 3.14..., ...])
Source code in src/circumplex/utils/angles.py
def degrees_to_radians(degrees: float | np.ndarray) -> float | np.ndarray:
    """Convert degrees to radians.

    Parameters
    ----------
    degrees
        Angle(s) in degrees

    Returns
    -------
    :
        Angle(s) in radians

    Examples
    --------
    >>> degrees_to_radians(180)
    3.141592653589793
    >>> degrees_to_radians(OCTANTS)
    array([1.57..., 2.35..., 3.14..., ...])

    """
    return np.radians(degrees)

radians_to_degrees

radians_to_degrees(radians: float | ndarray) -> float | np.ndarray

Convert radians to degrees.

PARAMETER DESCRIPTION
radians

Angle(s) in radians

TYPE: float | ndarray

RETURNS DESCRIPTION
float | ndarray

Angle(s) in degrees

Examples:

>>> radians_to_degrees(np.pi)
180.0
Source code in src/circumplex/utils/angles.py
def radians_to_degrees(radians: float | np.ndarray) -> float | np.ndarray:
    """Convert radians to degrees.

    Parameters
    ----------
    radians
        Angle(s) in radians

    Returns
    -------
    :
        Angle(s) in degrees

    Examples
    --------
    >>> radians_to_degrees(np.pi)
    180.0

    """
    return np.degrees(radians)

cosine_form

cosine_form(theta: NDArray[Shape[Any], Float], ampl: float, disp: float, elev: float) -> NDArray[Shape[Any], Float]

Cosine function with amplitude, displacement and elevation parameters.

This is the mathematical model used in the Structural Summary Method.

PARAMETER DESCRIPTION
theta

Angular positions in radians.

TYPE: NDArray[Shape[Any], Float]

ampl

Amplitude of the cosine curve.

TYPE: float

disp

Angular displacement in radians.

TYPE: float

elev

Elevation (mean level) of the cosine curve.

TYPE: float

RETURNS DESCRIPTION
NDArray[Shape[Any], Float]

Predicted values at each theta position.

Source code in src/circumplex/utils/angles.py
def cosine_form(
    theta: NDArray[Shape[Any], Float], ampl: float, disp: float, elev: float
) -> NDArray[Shape[Any], Float]:
    """
    Cosine function with amplitude, displacement and elevation parameters.

    This is the mathematical model used in the Structural Summary Method.

    Parameters
    ----------
    theta
        Angular positions in radians.
    ampl
        Amplitude of the cosine curve.
    disp
        Angular displacement in radians.
    elev
        Elevation (mean level) of the cosine curve.

    Returns
    -------
    :
        Predicted values at each theta position.
    """
    return elev + ampl * np.cos(theta - disp)

sort_angles

sort_angles(angles: NDArray[Shape[Any], Float], scores: NDArray[Shape[Any], Float]) -> tuple[NDArray[Shape[Any], Float], NDArray[Shape[Any], Float]]

Sort angles and corresponding scores in ascending order.

Source code in src/circumplex/utils/angles.py
def sort_angles(
    angles: NDArray[Shape[Any], Float], scores: NDArray[Shape[Any], Float]
) -> tuple[NDArray[Shape[Any], Float], NDArray[Shape[Any], Float]]:
    """Sort angles and corresponding scores in ascending order."""
    sorted_indices = np.argsort(angles)
    return np.array(angles)[sorted_indices], np.array(scores)[sorted_indices]