4784
Comment:
|
4826
Added rotation methods for Point()
|
Deletions are marked like this. | Additions are marked like this. |
Line 19: | Line 19: |
import math # required because of 'sqrt' in 'distanceTo' function (and now rotation) | import math # required because of 'sqrt' in 'distanceTo' function # also tan and atan for rotations. |
Line 70: | Line 71: |
# Err..this math is not exactly readable. It is elementary though, involving only Pythogoras and basic trig. | # Err..this math is not exactly readable. # It is elementary though, involving only Pythogoras and basic trig. |
Points & Rectangles
A pair of classes to provide points and rectangles.
Surprisingly, I haven't been able to find a single Python module providing such primitive support.
WxPython supports wxPoint and wxRect, but it lacks many basic functions (such as, say, adding two points together to produce a third point..!)
This code is lacking a zillion essential features (but interpoint distance can now be calculated). I only put in the ones I needed immediately. Please add, refactor, optimize, rename stuff to be more standard, etc., as you see fit..!
If there's an actual, accessible, easy-to-include Python module, not tied to a graphics library, that does this stuff already, please write about it here! No sense in reinventing the wheel. I've looked, but haven't found one. Hence this.
1 # Code is Public Domain.
2
3 import math # required because of 'sqrt' in 'distanceTo' function
4 # also tan and atan for rotations.
5
6 def normalize(x1, y1, x2, y2):
7 '''I am not sure what this is for, care to comment?'''
8 return min(x1,x2), min(y1,y2), max(x1,x2), max(y1,y2)
9
10 class Point:
11 def __init__(self, x, y):
12 self.x = x
13 self.y = y
14 def __add__(self, other):
15 return Point(self.x+other.x, self.y+other.y)
16 def __sub__(self, other):
17 return Point(self.x-other.x, self.y-other.y)
18 def __mul__( self, scalar ):
19 return Point(self.x*scalar, self.y*scalar)
20 def __div__(self, scalar):
21 return Point(self.x/scalar, self.y/scalar)
22 def __str__(self):
23 return "(%s, %s)" % (self.x, self.y)
24 def __repr__(self):
25 return "%s(%r, %r)" % (self.__class__.__name__, self.x, self.y)
26 def XY(self):
27 '''Returns a tuple (x,y).'''
28 return self.x,self.y
29 def Clone(self):
30 '''Returns a full copy of this point.'''
31 return Point(self.x, self.y)
32 def Integerize(self):
33 '''Rounds co-ordinate values to integers.'''
34 self.x = int(self.x)
35 self.y = int(self.y)
36 def Floatize(self):
37 '''Converts co-ordinate values to floating point (is this necessary?)'''
38 self.x = float(self.x)
39 self.y = float(self.y)
40 def DistanceTo(self,pt):
41 '''Distance between 2 points.'''
42 dy = self.y - pt.y
43 dx = self.x - pt.x
44 return sqrt(dy*dy + dx*dx)
45 def Move(newx,newy):
46 '''Changes coordinates to those given.'''
47 self.x = newx
48 self.y = newy
49 def MoveDelta(dx,dy):
50 '''Move to new (x+dx,y+dy)'''
51 self.x = self.x + dx
52 self.y = self.y + dy
53 def Rotate(self,theta):
54 '''Clockwise rotation about origin, theta in Degrees. Returns the new position as Point()'''
55 # Err..this math is not exactly readable.
56 # It is elementary though, involving only Pythogoras and basic trig.
57 r2 = sqr(self.x)+sqr(self.y)
58 tmp = math.tan(theta*math.pi/90 + math.atan(self.x/self.y))
59 ret = Point()
60 ret.x = math.sqrt(r2/(1+tmp*tmp))
61 ret.y = ret.x * tmp
62 return ret
63 def RotateAbout(self,OtherPoint,theta):
64 '''Clockwise rotation about another point. Returns a Point() at new position'''
65 tmpx = OtherPoint.x
66 tmpy = OtherPoint.y
67 self.MoveDelta(-tmpx,-tmpy)
68 tmpPoint = self.Rotate(theta)
69 tmpPoint.MoveDelta(tmpx,tmpy)
70 return tmpPoint
71
72
73 class Rect:
74 def __init__(self, pt1, pt2):
75 self.Set(pt1, pt2)
76 def Contains(self, pt):
77 x,y = pt.XY()
78 return self.left <= x <= self.right and self.top <= y <= self.bottom
79 def Set( self, pt1, pt2 ):
80 extrema = normalize(pt1.x, pt1.y, pt2.x, pt2.y)
81 self.left, self.top, self.right, self.bottom = extrema
82 def Overlaps(self, other):
83 return (self.right > other.left and self.left < other.right
84 and self.top < other.bottom and self.bottom > other.top)
85 def GetTL(self):
86 return Point(self.left, self.top)
87 def GetBR(self):
88 return Point(self.right, self.bottom)
89 def ExpandedBy(self, n):
90 p1 = Point(self.left-n, self.top+n)
91 p2 = Point(self.right+n, self.bottom+n)
92 return Rect(p1, p2)
93 def TransformedByFunction(self, foo):
94 p1 = Point(self.left, self.top)
95 p2 = Point(self.right, self.bottom)
96 return Rect(foo(p1), foo(p2))
97 def __str__( self ):
98 return "<Rect (%s,%s)-(%s,%s)>" % (self.left,self.top,
99 self.right,self.bottom)
100 def __repr__(self):
101 return "%s(%r, %r)" % (self.__class__.__name__,
102 Point(self.left, self.top),
103 Point(self.right, self.bottom))