Module datatap.geometry.point

Expand source code
from __future__ import annotations

from typing import Tuple, Union

from ..utils import basic_repr

PointJson = Tuple[float, float]

class Point:
        """
        A point in 2D space.  Also often used to represent a 2D vector.
        """

        x: float
        """
        The x-coordinate of the point.
        """

        y: float
        """
        The y-coordinate of the point.
        """

        @staticmethod
        def from_json(json: PointJson) -> Point:
                """
                Creates a `Point` from a `PointJson`.
                """
                return Point(json[0], json[1])

        def __init__(self, x: float, y: float, clip: bool = False):
                self.x = min(max(x, 0), 1) if clip else x
                self.y = min(max(y, 0), 1) if clip else y

        def to_json(self) -> PointJson:
                """
                Serializes this object as a `PointJson`.
                """
                return (self.x, self.y)

        def distance(self, other: Point) -> float:
                """
                Computes the scalar distance to another point.
                """
                return ((self.x - other.x) ** 2 + (self.y - other.y) ** 2) ** 0.5

        def assert_valid(self) -> None:
                """
                Asserts that this polygon is valid on the unit plane.
                """
                assert 0 <= self.x <= 1 and 0 <= self.y <= 1, f"Point coordinates must be between 0 and 1; failed on point {repr(self)}"

        def clip(self) -> Point:
                """
                Clips both coordinates of this point to the range [0, 1].
                """
                return Point(self.x, self.y, clip = True)

        def scale(self, factor: Union[float, int, Tuple[float, float], Point]) -> Point:
                """
                Resizes the point according to `factor`. The scaling factor can either
                be a scalar (`int` or `float`), in which case the point will be scaled
                by the same factor on both axes, or a point-like (`Tuple[float, float]`
                or `Point`), in which case the point will be scaled independently on
                each axis.
                """
                if isinstance(factor, (float, int)):
                        return self * factor
                if isinstance(factor, tuple):
                        return Point(self.x * factor[0], self.y * factor[1])
                return Point(self.x * factor.x, self.x * factor.y)

        def __add__(self, o: Point) -> Point:
                if isinstance(o, Point): # type: ignore - pyright complains about the isinstance check being redundant
                        return Point(self.x + o.x, self.y + o.y)
                return NotImplemented

        def __sub__(self, o: Point) -> Point:
                if isinstance(o, Point): # type: ignore - pyright complains about the isinstance check being redundant
                        return Point(self.x - o.x, self.y - o.y)
                return NotImplemented

        def __mul__(self, o: Union[int, float]) -> Point:
                if isinstance(o, (int, float)): # type: ignore - pyright complains about the isinstance check being redundant
                        return Point(self.x * o, self.y * o)
                return NotImplemented

        def __truediv__(self, o: Union[int, float]) -> Point:
                if isinstance(o, (int, float)): # type: ignore - pyright complains about the isinstance check being redundant
                        return Point(self.x / o, self.y / o)
                return NotImplemented

        def __repr__(self) -> str:
                return basic_repr("Point", self.x, self.y)

        def __hash__(self) -> int:
                return hash((self.x, self.y))

        def __eq__(self, other: Point) -> bool:
                if isinstance(other, Point): # type: ignore - pyright complains about the isinstance check being redundant
                        return self.x == other.x and self.y == other.y
                return NotImplemented

Classes

class Point (x: float, y: float, clip: bool = False)

A point in 2D space. Also often used to represent a 2D vector.

Expand source code
class Point:
        """
        A point in 2D space.  Also often used to represent a 2D vector.
        """

        x: float
        """
        The x-coordinate of the point.
        """

        y: float
        """
        The y-coordinate of the point.
        """

        @staticmethod
        def from_json(json: PointJson) -> Point:
                """
                Creates a `Point` from a `PointJson`.
                """
                return Point(json[0], json[1])

        def __init__(self, x: float, y: float, clip: bool = False):
                self.x = min(max(x, 0), 1) if clip else x
                self.y = min(max(y, 0), 1) if clip else y

        def to_json(self) -> PointJson:
                """
                Serializes this object as a `PointJson`.
                """
                return (self.x, self.y)

        def distance(self, other: Point) -> float:
                """
                Computes the scalar distance to another point.
                """
                return ((self.x - other.x) ** 2 + (self.y - other.y) ** 2) ** 0.5

        def assert_valid(self) -> None:
                """
                Asserts that this polygon is valid on the unit plane.
                """
                assert 0 <= self.x <= 1 and 0 <= self.y <= 1, f"Point coordinates must be between 0 and 1; failed on point {repr(self)}"

        def clip(self) -> Point:
                """
                Clips both coordinates of this point to the range [0, 1].
                """
                return Point(self.x, self.y, clip = True)

        def scale(self, factor: Union[float, int, Tuple[float, float], Point]) -> Point:
                """
                Resizes the point according to `factor`. The scaling factor can either
                be a scalar (`int` or `float`), in which case the point will be scaled
                by the same factor on both axes, or a point-like (`Tuple[float, float]`
                or `Point`), in which case the point will be scaled independently on
                each axis.
                """
                if isinstance(factor, (float, int)):
                        return self * factor
                if isinstance(factor, tuple):
                        return Point(self.x * factor[0], self.y * factor[1])
                return Point(self.x * factor.x, self.x * factor.y)

        def __add__(self, o: Point) -> Point:
                if isinstance(o, Point): # type: ignore - pyright complains about the isinstance check being redundant
                        return Point(self.x + o.x, self.y + o.y)
                return NotImplemented

        def __sub__(self, o: Point) -> Point:
                if isinstance(o, Point): # type: ignore - pyright complains about the isinstance check being redundant
                        return Point(self.x - o.x, self.y - o.y)
                return NotImplemented

        def __mul__(self, o: Union[int, float]) -> Point:
                if isinstance(o, (int, float)): # type: ignore - pyright complains about the isinstance check being redundant
                        return Point(self.x * o, self.y * o)
                return NotImplemented

        def __truediv__(self, o: Union[int, float]) -> Point:
                if isinstance(o, (int, float)): # type: ignore - pyright complains about the isinstance check being redundant
                        return Point(self.x / o, self.y / o)
                return NotImplemented

        def __repr__(self) -> str:
                return basic_repr("Point", self.x, self.y)

        def __hash__(self) -> int:
                return hash((self.x, self.y))

        def __eq__(self, other: Point) -> bool:
                if isinstance(other, Point): # type: ignore - pyright complains about the isinstance check being redundant
                        return self.x == other.x and self.y == other.y
                return NotImplemented

Class variables

var x : float

The x-coordinate of the point.

var y : float

The y-coordinate of the point.

Static methods

def from_json(json: PointJson) ‑> Point

Creates a Point from a PointJson.

Expand source code
@staticmethod
def from_json(json: PointJson) -> Point:
        """
        Creates a `Point` from a `PointJson`.
        """
        return Point(json[0], json[1])

Methods

def assert_valid(self) ‑> None

Asserts that this polygon is valid on the unit plane.

Expand source code
def assert_valid(self) -> None:
        """
        Asserts that this polygon is valid on the unit plane.
        """
        assert 0 <= self.x <= 1 and 0 <= self.y <= 1, f"Point coordinates must be between 0 and 1; failed on point {repr(self)}"
def clip(self) ‑> Point

Clips both coordinates of this point to the range [0, 1].

Expand source code
def clip(self) -> Point:
        """
        Clips both coordinates of this point to the range [0, 1].
        """
        return Point(self.x, self.y, clip = True)
def distance(self, other: Point) ‑> float

Computes the scalar distance to another point.

Expand source code
def distance(self, other: Point) -> float:
        """
        Computes the scalar distance to another point.
        """
        return ((self.x - other.x) ** 2 + (self.y - other.y) ** 2) ** 0.5
def scale(self, factor: Union[float, int, Tuple[float, float], Point]) ‑> Point

Resizes the point according to factor. The scaling factor can either be a scalar (int or float), in which case the point will be scaled by the same factor on both axes, or a point-like (Tuple[float, float] or Point), in which case the point will be scaled independently on each axis.

Expand source code
def scale(self, factor: Union[float, int, Tuple[float, float], Point]) -> Point:
        """
        Resizes the point according to `factor`. The scaling factor can either
        be a scalar (`int` or `float`), in which case the point will be scaled
        by the same factor on both axes, or a point-like (`Tuple[float, float]`
        or `Point`), in which case the point will be scaled independently on
        each axis.
        """
        if isinstance(factor, (float, int)):
                return self * factor
        if isinstance(factor, tuple):
                return Point(self.x * factor[0], self.y * factor[1])
        return Point(self.x * factor.x, self.x * factor.y)
def to_json(self) ‑> Tuple[float, float]

Serializes this object as a PointJson.

Expand source code
def to_json(self) -> PointJson:
        """
        Serializes this object as a `PointJson`.
        """
        return (self.x, self.y)