Newer
Older
# -*- coding: utf-8 -*-
"""
Point.py - Extension of QPointF which adds a few missing methods.
Copyright 2010 Luke Campagnola
Distributed under MIT/X11 license. See license.txt for more infomation.
"""
from PyQt4 import QtCore
from math import acos
def clip(x, mn, mx):
if x > mx:
return mx
if x < mn:
return mn
return x
class Point(QtCore.QPointF):
"""Extension of QPointF which adds a few missing methods."""
def __init__(self, *args):
if len(args) == 1:
if isinstance(args[0], QtCore.QSizeF):
QtCore.QPointF.__init__(self, float(args[0].width()), float(args[0].height()))
return
elif hasattr(args[0], '__getitem__'):
QtCore.QPointF.__init__(self, float(args[0][0]), float(args[0][1]))
return
elif type(args[0]) in [float, int]:
QtCore.QPointF.__init__(self, float(args[0]), float(args[0]))
return
elif len(args) == 2:
QtCore.QPointF.__init__(self, args[0], args[1])
return
QtCore.QPointF.__init__(self, *args)
def __reduce__(self):
return (Point, (self.x(), self.y()))
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
def __getitem__(self, i):
if i == 0:
return self.x()
elif i == 1:
return self.y()
else:
raise IndexError("Point has no index %d" % i)
def __setitem__(self, i, x):
if i == 0:
return self.setX(x)
elif i == 1:
return self.setY(x)
else:
raise IndexError("Point has no index %d" % i)
def __radd__(self, a):
return self._math_('__radd__', a)
def __add__(self, a):
return self._math_('__add__', a)
def __rsub__(self, a):
return self._math_('__rsub__', a)
def __sub__(self, a):
return self._math_('__sub__', a)
def __rmul__(self, a):
return self._math_('__rmul__', a)
def __mul__(self, a):
return self._math_('__mul__', a)
def __rdiv__(self, a):
return self._math_('__rdiv__', a)
def __div__(self, a):
return self._math_('__div__', a)
def __rpow__(self, a):
return self._math_('__rpow__', a)
def __pow__(self, a):
return self._math_('__pow__', a)
def _math_(self, op, x):
#print "point math:", op
try:
return Point(getattr(QtCore.QPointF, op)(self, x))
except:
x = Point(x)
return Point(getattr(self[0], op)(x[0]), getattr(self[1], op)(x[1]))
def length(self):
return (self[0]**2 + self[1]**2) ** 0.5
def angle(self, a):
"""Returns the angle between this vector and the vector a."""
n1 = self.length()
n2 = a.length()
if n1 == 0. or n2 == 0.:
return None
## Probably this should be done with arctan2 instead..
ang = acos(clip(self.dot(a) / (n1 * n2), -1.0, 1.0)) ### in radians
c = self.cross(a)
if c > 0:
ang *= -1.
return ang
def dot(self, a):
a = Point(a)
return self[0]*a[0] + self[1]*a[1]
def cross(self, a):
a = Point(a)
return self[0]*a[1] - self[1]*a[0]
def __repr__(self):
return "Point(%f, %f)" % (self[0], self[1])
def min(self):
return min(self[0], self[1])
def max(self):
return max(self[0], self[1])