This repository has been archived on 2023-03-25. You can view files and clone it, but cannot push or open issues or pull requests.
mightyscape-1.1-deprecated/extensions/fablabchemnitz/inkscape_helper/Coordinate.py

105 lines
2.8 KiB
Python
Raw Normal View History

2020-07-30 01:16:18 +02:00
from math import *
def inner_product(a, b):
return a.x * b.x + a.y * b.y
class Coordinate(object):
"""
Basic (x, y) coordinate class (or should it be called vector?) which allows some simple operations.
"""
def __init__(self, x, y):
self.x = float(x)
self.y = float(y)
#polar coordinates
@property
def t(self):
angle = atan2(self.y, self.x)
if angle < 0:
angle += pi * 2
return angle
@t.setter
def t(self, value):
length = self.r
self.x = cos(value) * length
self.y = sin(value) * length
@property
def r(self):
return hypot(self.x, self.y)
@r.setter
def r(self, value):
angle = self.t
self.x = cos(angle) * value
self.y = sin(angle) * value
def __repr__(self):
return self.__str__()
def __str__(self):
return "(%f, %f)" % (self.x, self.y)
def __eq__(self, other):
return self.x == other.x and self.y == other.y
def __add__(self, other):
return Coordinate(self.x + other.x, self.y + other.y)
def __sub__(self, other):
return Coordinate(self.x - other.x, self.y - other.y)
def __mul__(self, factor):
return Coordinate(self.x * factor, self.y * factor)
def __neg__(self):
return Coordinate(-self.x, -self.y)
def __rmul__(self, other):
return self * other
def __div__(self, quotient):
return Coordinate(self.x / quotient, self.y / quotient)
def __truediv__(self, quotient):
return self.__div__(quotient)
def dot(self, other):
"""dot product"""
return self.x * other.x + self.y * other.y
def cross_norm(self, other):
""""the norm of the cross product"""
self.x * other.y - self.y * other.x
def close_enough_to(self, other, limit=1E-9):
return (self - other).r < limit
class IntersectionError(ValueError):
"""Raised when two lines do not intersect."""
def on_segment(pt, start, end):
"""Check if pt is between start and end. The three points are presumed to be collinear."""
pt -= start
end -= start
ex, ey = end.x, end.y
px, py = pt.x, pt.y
px *= cmp(ex, 0)
py *= cmp(ey, 0)
return px >= 0 and px <= abs(ex) and py >= 0 and py <= abs(ey)
def intersection (s1, e1, s2, e2, on_segments = True):
D = (s1.x - e1.x) * (s2.y - e2.y) - (s1.y - e1.y) * (s2.x - e2.x)
if D == 0:
raise IntersectionError("Lines from {s1} to {e1} and {s2} to {e2} are parallel")
N1 = s1.x * e1.y - s1.y * e1.x
N2 = s2.x * e2.y - s2.y * e2.x
I = ((s2 - e2) * N1 - (s1 - e1) * N2) / D
if on_segments and not (on_segment(I, s1, e1) and on_segment(I, s2, e2)):
raise IntersectionError("Intersection {0} is not on line segments [{1} -> {2}] [{3} -> {4}]".format(I, s1, e1, s2, e2))
return I