Source code for ensemble.tools.geometry

"""
Auxiliary geometry
==================
"""


# ============================================================================
# STANDARD  IMPORTS
# ============================================================================

import numpy as np
from dataclasses import dataclass
from functools import cached_property

# ============================================================================
# INTERNAL IMPORTS
# ============================================================================

# ============================================================================
# CLASS AND DEFINITIONS
# ============================================================================


[docs]@dataclass class Point: x: float y: float @cached_property def vect(self): """Colection""" return np.asarray((self.x, self.y))
[docs] def norm(self): """Norm""" return np.linalg.norm(self.vect)
[docs] def mean(self): """Mean""" return np.asarray(self.vect).mean()
[docs] def distanceto(self, point): """Distance to other""" return np.linalg.norm(point.vect - self.vect)
[docs] def findperpendicular(self): """Find a perpendicular vector""" try: ac_wise = ( np.array([-self.y / self.x, 1]) if self.x > 0 else np.array([self.y / self.x, -1]) ) return Point(ac_wise[0], ac_wise[1]) except ZeroDivisionError: c_wise = ( np.array([1, -self.x / self.y]) if self.y > 0 else np.array([-1, self.x / self.y]) ) return Point(-c_wise[0], -c_wise[1])
[docs] def isbehindof(self, m): """Returns true if point infront this one""" # Based on https://stackoverflow.com/questions/1560492/how-to-tell-whether-a-point-is-to-the-right-or-left-side-of-a-line # A : acwise vector, B: origin, M: point # sign((Bx - Ax) * (Y - Ay) - (By - Ay) * (X - Ax)) n = self.findperpendicular() a = n + self b = self return ( np.sign((b.x - a.x) * (m.y - a.y) - (b.y - a.y) * (m.x - a.x)) > 0 )
[docs] def isinfrontof(self, m): """Returns true if point behind of this one""" n = self.findperpendicular() a = n + self b = self return ( np.sign((b.x - a.x) * (m.y - a.y) - (b.y - a.y) * (m.x - a.x)) < 0 )
def __add__(self, point): return Point(self.x + point.x, self.y + point.y)
if __name__ == "__main__": a = Point(1, 1) b = Point(3, 3) print( f""" This is: {repr(a)}, norm of: {a.norm()}, mean of: {a.mean()}, this is: {repr(b)}, distance from {repr(a)} to {repr(b)}: {a.distanceto(b)}, Anti clockwise vector to {repr(a)}: {a.findperpendicular()}, Is {repr(a)} in front of {repr(b)}: {a.isinfrontof(b)}, Is {repr(a)} behind of {repr(b)}: {a.isbehindof(b)}, """ )