Source code for miney.point

from typing import Union
from math import sqrt, acos, degrees


[docs] class Point: """ A point is a position inside a three dimensional system. """ def __init__(self, x: Union[int, float] = 0, y: Union[int, float] = 0, z: Union[int, float] = 0): self.x = x self.y = y self.z = z
[docs] def distance(self, b: "Point") -> float: """ Measure the distance between this point and Point b. :param b: Another Point :return: Distance """ return sqrt((b.x - self.x) ** 2 + (b.y - self.y) ** 2 + (b.z - self.z) ** 2)
[docs] def center(self, b: "Point") -> "Point": """ Get the exact point in the center between this point and point b. :param b: Another Point :return: The center point """ return (self + b) / 2
def __add__(self, other: "Point") -> "Point": return Point(self.x + other.x, self.y + other.y, self.z + other.z) def __sub__(self, other: "Point") -> "Point": return Point(self.x - other.x, self.y - other.y, self.z - other.z) def __mul__(self, scalar: Union[int, float]) -> "Point": if not isinstance(scalar, (int, float)): return NotImplemented return Point(self.x * scalar, self.y * scalar, self.z * scalar) def __rmul__(self, scalar: Union[int, float]) -> "Point": return self.__mul__(scalar) def __truediv__(self, scalar: Union[int, float]) -> "Point": if not isinstance(scalar, (int, float)): return NotImplemented return Point(self.x / scalar, self.y / scalar, self.z / scalar) def __iadd__(self, o): self.x += o.x self.y += o.y self.z += o.z return self def __isub__(self, o): self.x -= o.x self.y -= o.y self.z -= o.z return self def __neg__(self): return Point(-self.x, -self.y, -self.z)
[docs] def length(self) -> float: """ Returns the distance to the x=0, y=0, z=0 point. :return: :rtype: """ return sqrt((self.x * self.x) + (self.y * self.y) + (self.z * self.z))
def normalize(self): return Point((self.x / self.length()), (self.y / self.length()), (self.z / self.length())) def angle(self, b): m = self.x * b.x + self.y * b.y + self.z * b.z return degrees(acos(m / (self.length() * b.length()))) def __len__(self) -> int: """ Return the number of coordinates, which is always 3. Allows conversion to list or tuple. """ return 3 def __iter__(self): """ Allow the point to be converted to a dict. """ yield 'x', self.x yield 'y', self.y yield 'z', self.z def __getitem__(self, item_key: Union[int, str]): """ Allow accessing coordinates by index (0=x, 1=y, 2=z) or attribute name. """ if isinstance(item_key, int): if item_key == 0: return self.x elif item_key == 1: return self.y elif item_key == 2: return self.z else: raise IndexError("Point index out of range") # Fallback to original behavior for string keys return self.__getattribute__(item_key) def __repr__(self): return f"<Luanti Point(x={self.x}, y={self.y}, z={self.z})>"