Files
old-krovovi-kalkulator/helix/models/coordinate.py
2017-11-07 09:23:57 +01:00

88 lines
2.8 KiB
Python

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)