Source code for neoscore.core.spanner_2d

from __future__ import annotations

import math
from typing import cast

from neoscore.core.math_helpers import point_angle
from neoscore.core.point import Point, PointDef
from neoscore.core.positioned_object import PositionedObject, render_cached_property
from neoscore.core.spanner import Spanner
from neoscore.core.units import Unit


[docs]class Spanner2D(Spanner): """A 2-dimensional :obj:`.Spanner`."""
[docs] def __init__(self, end_pos: PointDef, end_parent: PositionedObject): """ Args: end_pos: The end point. end_parent: The parent for the ending position. """ end_pos = Point.from_def(end_pos) super().__init__(end_pos.x, end_parent) self._end_y = end_pos.y
@property def end_y(self) -> Unit: """The y position of the endpoint as specified.""" return self._end_y @end_y.setter def end_y(self, value: Unit): self._end_y = value @property def end_pos(self) -> Point: return Point(self._end_x, self._end_y) @end_pos.setter def end_pos(self, value: PointDef): value = Point.from_def(value) self._end_x = value.x self._end_y = value.y @render_cached_property def spanner_2d_length(self) -> Unit: """The 2d length of the spanner. This takes into account both the x and y-axis. For only the horizontal length, use :obj:`.Spanner.spanner_x_length`. """ return cast(PositionedObject, self).distance_to(self.end_parent, self.end_pos) @render_cached_property def angle(self) -> float: """The angle from the start to end point in degrees. The angle goes from the positive X axis to the end point. Positive angles go clockwise. """ return math.degrees(point_angle(self._relative_end_pos)) @render_cached_property def _relative_end_pos(self) -> Point: return cast(PositionedObject, self).map_to(self.end_parent) + self.end_pos