Skip to content

Instantly share code, notes, and snippets.

@tfeldmann
Created June 16, 2016 13:48
Show Gist options
  • Save tfeldmann/4c4b56807f4447266bc6f722bf63705b to your computer and use it in GitHub Desktop.
Save tfeldmann/4c4b56807f4447266bc6f722bf63705b to your computer and use it in GitHub Desktop.
A fast, feature-rich and easy-to-use python 2D vector class based on complex numbers
""" A python 2D vector class based on complex numbers
"""
import cmath
class Vector(complex):
@classmethod
def fromPolar(cls, r, phi):
return cls(cmath.rect(r, phi))
@classmethod
def fromQPoint(cls, qpoint):
return cls(qpoint.x(), qpoint.y())
@property
def x(self):
return self.real
@property
def y(self):
return self.imag
@property
def xy(self):
return (self.x, self.y)
@property
def r(self):
return abs(self)
@property
def phi(self):
return self.normalizeAngle(cmath.phase(self))
@property
def rphi(self):
return (self.r, self.phi)
@property
def qpoint(self):
from PySide import QtCore
return QtCore.QPointF(self.x, self.y)
@staticmethod
def normalizeAngle(phi):
return phi % (2 * cmath.pi)
@property
def unitVector(self, *, suppressZeroDivisionError=True):
length = abs(self)
if length == 0 and suppressZeroDivisionError:
return Vector(1, 0)
else:
return self / length
unitV = unitVector
@property
def normalVector(self):
return Vector(self.y, -self.x)
normal = normalVector
def isBetweenAngles(self, startAngle, stopAngle):
phi = self.normalizeAngle(cmath.phase(self))
fromPhi = self.normalizeAngle(startAngle)
toPhi = self.normalizeAngle(stopAngle)
if fromPhi <= toPhi:
return fromPhi <= phi <= toPhi
return fromPhi <= phi or phi <= toPhi
def translate(self, dx, dy):
return self + Vector(dx, dy)
def rotate(self, phi, center=None):
if not center:
return self * cmath.exp(1j * phi)
else:
vec = center.vectorTo(self)
return center + vec * cmath.exp(1j * phi)
def scale(self, factorX, factorY):
return Vector(self.x * factorX, self.y * factorY)
def vectorTo(self, point):
return point - self
to = vectorTo
def __add__(self, other):
return Vector(super().__add__(other))
def __pos__(self):
return Vector(super().__pos__())
def __neg__(self):
return Vector(super().__neg__())
def __sub__(self, other):
return Vector(super().__sub__(other))
def __mul__(self, other):
return Vector(super().__mul__(other))
def __truediv__(self, other):
return Vector(super().__truediv__(other))
def __round__(self):
return Vector(round(self.x), round(self.y))
def __repr__(self):
return '<Vector(x=%.3f, y=%.3f)>' % self.xy
def __str__(self):
return '(%.3f, %.3f)' % self.xy
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment