first commit
This commit is contained in:
87
helix/models/coordinate.py
Normal file
87
helix/models/coordinate.py
Normal file
@@ -0,0 +1,87 @@
|
||||
import json
|
||||
from math import hypot
|
||||
import math
|
||||
from helix.functions import fequal
|
||||
|
||||
|
||||
class Coordinate(object):
|
||||
def __init__(self, x, y, rotation=0., calculate_rounding=True):
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.rotation = rotation
|
||||
|
||||
if calculate_rounding:
|
||||
self.__rounded_x = round(x, 3)
|
||||
self.__rounded_y = round(y, 3)
|
||||
else:
|
||||
self.__rounded_x = x
|
||||
self.__rounded_y = y
|
||||
|
||||
def __eq__(self, other):
|
||||
if self is other:
|
||||
return True
|
||||
if not isinstance(other, self.__class__):
|
||||
return False
|
||||
if fequal(self.rotation, other.rotation, delta=1e-3):
|
||||
return fequal(self.x, other.x, delta=1e-3) and fequal(self.y, other.y, delta=1e-3)
|
||||
return False
|
||||
|
||||
@property
|
||||
def dictionary(self):
|
||||
return {"x": self.x, "y": self.y, "rotation": self.rotation}
|
||||
|
||||
def __repr__(self):
|
||||
return json.dumps(self.dictionary, sort_keys=True)
|
||||
|
||||
def __sub__(self, other):
|
||||
if fequal(self.rotation, other.rotation, delta=1e-1):
|
||||
return Coordinate(self.x - other.x, self.y - other.y, self.rotation)
|
||||
else:
|
||||
raise ValueError
|
||||
|
||||
def __add__(self, other):
|
||||
if abs(self.rotation - other.rotation) < 1e-3:
|
||||
return Coordinate(self.x + other.x, self.y + other.y, self.rotation, calculate_rounding=False)
|
||||
else:
|
||||
raise ValueError
|
||||
|
||||
def __abs__(self):
|
||||
return self.length()
|
||||
|
||||
def __lt__(self, other):
|
||||
if self == other:
|
||||
return False
|
||||
if self.y < other.y:
|
||||
return True
|
||||
elif other.y < self.y:
|
||||
return False
|
||||
return self.x < other.x
|
||||
|
||||
def __round__(self, n=0):
|
||||
return Coordinate(round(self.x, n), round(self.y, n), self.rotation)
|
||||
|
||||
def __hash__(self):
|
||||
return hash(self.__rounded_x) ^ hash(self.__rounded_y) ^ hash(self.rotation)
|
||||
|
||||
# Returns a Coordinate based on self, rotated by self's rotation
|
||||
def rotate(self):
|
||||
rotation = math.radians(self.rotation)
|
||||
x = self.x * math.cos(rotation) - self.y * math.sin(rotation)
|
||||
y = self.x * math.sin(rotation) + self.y * math.cos(rotation)
|
||||
return Coordinate(x, y)
|
||||
|
||||
# Returns a Coordinate based on self, rotated by self's negative rotation
|
||||
def unrotate(self):
|
||||
rotation = math.radians(-self.rotation)
|
||||
x = self.x * math.cos(rotation) - self.y * math.sin(rotation)
|
||||
y = self.x * math.sin(rotation) + self.y * math.cos(rotation)
|
||||
return Coordinate(x, y)
|
||||
|
||||
def scale(self, x, y):
|
||||
return Coordinate(self.x * x, self.y * y, self.rotation)
|
||||
|
||||
def neg_translate(self, other):
|
||||
return Coordinate(self.x - other.x, self.y - other.y, self.rotation)
|
||||
|
||||
def length(self):
|
||||
return hypot(self.x, self.y)
|
||||
Reference in New Issue
Block a user