# 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, json)

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, self.y * factor)
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, json)

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, self.y * factor)
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, json)``````

### 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, self.y * factor)
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)``````