root/trunk/RBRapier/RBRapier/Tools/RectangleBase.py

Revision 704, 8.9 kB (checked in by sholloway, 5 years ago)

*** empty log message ***

Line 
1 #!/usr/bin/env python
2 ##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 ##~ License
4 ##~
5 ##- The RuneBlade Foundation library is intended to ease some
6 ##- aspects of writing intricate Jabber, XML, and User Interface (wxPython, etc.)
7 ##- applications, while providing the flexibility to modularly change the
8 ##- architecture. Enjoy.
9 ##~
10 ##~ Copyright (C) 2002  TechGame Networks, LLC.
11 ##~
12 ##~ This library is free software; you can redistribute it and/or
13 ##~ modify it under the terms of the BSD style License as found in the
14 ##~ LICENSE file included with this distribution.
15 ##~
16 ##~ TechGame Networks, LLC can be reached at:
17 ##~ 3578 E. Hartsel Drive #211
18 ##~ Colorado Springs, Colorado, USA, 80920
19 ##~
20 ##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
21
22 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23 #~ Imports
24 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25
26 import operator
27 import Numeric
28 from Transformations import TransformPrimitive3dh
29 from Transformations2d import TransformPrimitive2dh
30 from Vector import LinearMapping, LinearDimMapping
31
32 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
33 #~ Definitions
34 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
35
36 class RectangleBase(object):
37     """
38     >>> r = RectangleBase([2, 3, 5, 7])
39     >>> r.Rectangle
40     [2, 3, 5, 7]
41     >>> r.X1, r.Y1, r.Width, r.Height
42     (2, 3, 5, 7)
43     >>> r.X1, r.Y1, r.X2, r.Y2
44     (2, 3, 7, 10)
45     >>> r.Position, r.Dimension
46     ([2, 3], [5, 7])
47     >>> r.Position1, r.Position2
48     ([2, 3], [7, 10])
49     >>> r.AspectRatio
50     1.3999999999999999
51     >>> r.X, r.Y = 11, 13; r.Rectangle
52     [11, 13, 5, 7]
53     >>> r.X2, r.Y2 = 23, 29; r.Rectangle
54     [18, 22, 5, 7]
55     >>> r.Position1 = 1,2; r.Rectangle
56     [1, 2, 5, 7]
57     >>> r.Position2 = 31, 37; r.Rectangle
58     [1, 2, 30, 35]
59     """
60
61     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
62     #~ Special
63     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
64
65     def __init__(self, Rectangle=None):
66         self.Rectangle = Rectangle or [-1, -1, 2, 2]
67
68     def __repr__(self):
69         return "<x:%s y:%s w:%s h:%s>" % tuple(self.Rectangle)
70
71     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
72     #~ Public properties
73     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
74
75     def GetX1(self): return self.Rectangle[0]
76     def SetX1(self, X): self.Rectangle[0] = X
77     X = X1 = property(GetX1, SetX1)
78     def GetX2(self): return self.Rectangle[0] + self.Rectangle[2]
79     def SetX2(self, X): self.Rectangle[0] = X - self.Rectangle[2]
80     X2 = property(GetX2, SetX2)
81     def GetWidth(self): return self.Rectangle[2]
82     def SetWidth(self, width):  self.Rectangle[2] = width
83     Width = property(GetWidth, SetWidth)
84
85     def GetY1(self): return self.Rectangle[1]
86     def SetY1(self, Y): self.Rectangle[1] = Y
87     Y = Y1 = property(GetY1, SetY1)
88     def GetY2(self): return self.Rectangle[1] + self.Rectangle[3]
89     def SetY2(self, Y): self.Rectangle[1] = Y - self.Rectangle[3]
90     Y2 = property(GetY2, SetY2)
91     def GetHeight(self): return self.Rectangle[3]
92     def SetHeight(self, height):  self.Rectangle[3] = height
93     Height = property(GetHeight, SetHeight)
94
95     def GetPosition(self): return self.Rectangle[0:2]
96     def SetPosition(self, position): self.Rectangle[0:2] = self.Rectangle.__class__(position)
97     Position = Position1 = property(GetPosition, SetPosition)
98
99     def GetPosition2(self): return map(operator.add, self.Rectangle[0:2], self.Rectangle[2:4])
100     def SetPosition2(self, position): self.Rectangle[2:4] = map(operator.sub, self.Rectangle.__class__(position), self.Rectangle[0:2])
101     Position2 = property(GetPosition2, SetPosition2)
102
103     def GetDimension(self): return self.Rectangle[2:4]
104     def SetDimension(self, dimension): self.Rectangle[2:4] = self.Rectangle.__class__(dimension)
105     Dimension = property(GetDimension, SetDimension)
106
107     def GetAspectRatio(self): return float(self.Rectangle[3]) / float(self.Rectangle[2])
108     AspectRatio = property(GetAspectRatio)
109
110     def GetBox(self):
111         x, y, w, h = self.GetRectangle()
112         return (x, y), (x+w, y+h)
113     def SetBox(self, box):
114         (x0, y0), (x1, y1) = box
115         w, h = x1-x0, y1-y0
116         return self.SetRectangle(x0,y0,w,h)
117
118     def GetPts(self):
119         return self.GetBox()
120     def SetPts(self, pos0, pos1):
121         return self.SetBox((pos0, pos1))
122
123     def GetRectangle(self):
124         return map(float, self.Rectangle)
125     def SetRectangle(self, *args):
126         if len(args) == 1: args = args[0]
127         self.Rectangle[:] = self.Rectangle.__class__(args)
128
129     def MapPointTo(self, point, *args, **kw):
130         return self.MapPointsTo([point], *args, **kw)[0]
131
132     def MapPointsTo(self, points, xspan=(-1., 1.), yspan=None, flipx=False, flipy=False):
133         xspan, yspan = xspan or yspan, yspan or xspan
134         if flipx: xspan = xspan[1], xspan[0]
135         if flipy: yspan = yspan[1], yspan[0]
136         x0, y0, w, h = self.Rectangle
137         xfn = LinearMapping((x0, x0+w), xspan or yspan)
138         yfn = LinearMapping((y0, y0+h), yspan or xspan)
139         return [(xfn(x),yfn(y)) for x,y in points]
140
141     def MapPointsFrom(self, point, *args, **kw):
142         return self.MapPointsFrom([point], *args, **kw)[0]
143
144     def MapPointsFrom(self, points, xspan=(-1., 1.), yspan=None, flipx=False, flipy=False):
145         xspan, yspan = xspan or yspan, yspan or xspan
146         if flipx: xspan = xspan[1], xspan[0]
147         if flipy: yspan = yspan[1], yspan[0]
148         x0, y0, w, h = self.Rectangle
149         xfn = LinearMapping(xspan, (x0, x0+w))
150         yfn = LinearMapping(yspan, (y0, y0+h))
151         return [(xfn(x),yfn(y)) for x,y in points]
152
153 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
154
155 class RectangleMappingBase(object):
156     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
157     #~ Constants / Variables / Etc.
158     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
159
160     _fromrect = RectangleBase()
161     _torect = RectangleBase()
162
163     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
164     #~ Public Methods
165     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
166
167     def __init__(self, fromrect=None, torect=None):
168         if isinstance(fromrect, (list, tuple)):
169             self._fromrect = RectangleBase(fromrect)
170         elif fromrect is not None:
171             self._fromrect = fromrect
172         if isinstance(torect, (list, tuple)):
173             self._torect = RectangleBase(torect)
174         elif torect is not None:
175             self._torect = torect
176
177     def __repr__(self):
178         return "<%s from:%r to:%r>" % (self.__class__.__name__, self.MapFrom, self.MapTo)
179
180     def GetMapTo(self):
181         return self._torect
182     def SetMapTo(self, torect):
183         self._torect = torect
184     def DelMapTo(self):
185         del self._torect
186     MapTo = property(GetMapTo, SetMapTo, DelMapTo)
187
188     def GetMapFrom(self):
189         return self._fromrect
190     def SetMapFrom(self, fromrect):
191         self._fromrect = fromrect
192     def DelMapFrom(self):
193         del self._fromrect
194     MapFrom = property(GetMapFrom, SetMapFrom, DelMapFrom)
195
196     def _GetMapping(self, frombox, tobox):
197         (x0f, y0f), (x1f, y1f) = frombox
198         (x0t, y0t), (x1t, y1t) = tobox
199         sx, tx = LinearMapping((x0f, x1f), (x0t, x1t), False)
200         sy, ty = LinearMapping((y0f, y1f), (y0t, y1t), False)
201         return (sx, tx), (sy,ty)
202
203 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
204
205 class RectangleMappingMatrix3dh(RectangleMappingBase, TransformPrimitive3dh):
206     def asArray4x4(self):
207         (sx, tx), (sy, ty) = self._GetMapping(self.GetMapFrom().GetBox(), self.GetMapTo().GetBox())
208         result = Numeric.asarray([
209             [sx,  0,  0, tx],
210             [ 0, sy,  0, ty],
211             [ 0,  0,  1,  0],
212             [ 0,  0,  0,  1]], self.NumericType)
213         return result
214
215     def asInverse4x4_(self):
216         (sx, tx), (sy, ty) = self._GetMapping(self.GetMapTo().GetBox(), self.GetMapFrom().GetBox())
217         result = Numeric.asarray([
218             [sx,  0,  0, tx],
219             [ 0, sy,  0, ty],
220             [ 0,  0,  1,  0],
221             [ 0,  0,  0,  1]], self.NumericType)
222         return result
223
224 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
225
226 class RectangleMappingMatrix2dh(RectangleMappingBase, TransformPrimitive2dh):
227     def asArray4x4(self):
228         (sx, tx), (sy, ty) = self._GetMapping(self.GetMapFrom().GetBox(), self.GetMapTo().GetBox())
229         result = Numeric.asarray([
230             [sx,  0, tx],
231             [ 0, sy, ty],
232             [ 0,  0,  1]], self.NumericType)
233         return result
234
235     def asInverse4x4_(self):
236         (sx, tx), (sy, ty) = self._GetMapping(self.GetMapTo().GetBox(), self.GetMapFrom().GetBox())
237         result = Numeric.asarray([
238             [sx,  0, tx],
239             [ 0, sy, ty],
240             [ 0,  0,  1]], self.NumericType)
241         return result
242
243 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
244 #~ Testing
245 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
246
247 if __name__=='__main__':
248     print "Testing..."
249     import doctest, RectangleBase as _TestMod
250     doctest.testmod(_TestMod)
251     print "Test complete."
252
Note: See TracBrowser for help on using the browser.