1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 __docformat__ = 'reStructuredText'
20
21 from pytilities.overloading import \
22 overloaded, Overload, Param, CompositeParam
23 from pytilities.types import NumberType
24 from . import Vector, BoundVector
32
33 """
34 A rectangle identified by two points.
35
36 The rectangle stores left, top, right, and bottom values.
37
38 Coordinates are based on screen coordinates.
39
40 origin top
41 +-----> x increases |
42 | left -+- right
43 v |
44 y increases bottom
45
46 Instance methods:
47
48 - `copy`: Make a shallow copy
49 - `contains`: Is a vector inside?
50 - `overlaps`: Does a rectangle overlap?
51 - `inflate`: grow (or shrink)
52 - `move_to`: move entire rectangle to a spot
53 - `move_by`: move entire rectangle by an amount
54
55 Instance properties:
56
57 - `bounds`: Read-write, all rectangle coordinates
58 - `center`: Read-write, center of the rectangle
59 - `width`: Read-write, width of the rectangle
60 - `height`: Read-write, height of the rectangle
61 - `size`: Read-write, size of the rectangle
62 - `left`: Read-write, left edge of rectangle
63 - `top`: Read-write, top edge of rectangle
64 - `right`: Read-write, right edge of rectangle
65 - `bottom`: Read-write, bottom edge of rectangle
66 - `top_left`: Read-write, top-left corner
67 - `top_right`: Read-write, top-right corner
68 - `bottom_left`: Read-write, bottom-left corner
69 - `bottom_right`: Read-write, bottom-right corner
70
71 Operators:
72
73 str(s)
74 repr(s)
75 """
76
78 """
79 Construct a rectangle.
80
81 Overloaded, parameters:
82
83 :a:
84 `left` :: float | int
85 `top` :: float | int
86 `right` :: float | int
87 `bottom` :: float | int
88
89 :b:
90 `top_left` :: Vector
91 `bottom_right` :: Vector
92 """
93
94 self.bounds = args
95
96 self.__size = BoundVector(
97 self, "width", "height")
98
99 self.__center = BoundVector(
100 self, "__center_x", "__center_y")
101
102 self.__top_left = BoundVector(
103 self, "left", "top")
104
105 self.__top_right = BoundVector(
106 self, "right", "top")
107
108 self.__bottom_left = BoundVector(
109 self, "left", "bottom")
110
111 self.__bottom_right = BoundVector(
112 self, "right", "bottom")
113
116
118 """Returns shallow copy"""
119 return self.__copy__
120
121 @property
123 """Read-write, all rectangle coordinates
124
125 Returns (left, top, right, bottom)
126
127 Overloaded, set parameters:
128
129 :a:
130 `left` :: float | int
131 `top` :: float | int
132 `right` :: float | int
133 `bottom` :: float | int
134
135 :b:
136 `top_left` :: Vector
137 `bottom_right` :: Vector
138 """
139 return (self.left, self.top, self.right, self.bottom)
140
149
158
159 @bounds.setter
160 @overloaded((
161 Overload(__set_bounds_numbers,
162 CompositeParam("args", (
163 Param("left", NumberType),
164 Param("top", NumberType),
165 Param("right", NumberType),
166 Param("bottom", NumberType)))),
167 Overload(__set_bounds_points,
168 CompositeParam("args", (
169 Param("top_left"),
170 Param("bottom_right"))))))
173
174 @property
177
178 @__center_x.setter
183
184 @property
187
188 @__center_y.setter
193
194 @property
196 """
197 Read-write, center of the rectangle :: bound Vector
198
199 Changing the center does not change the size.
200 """
201 return self.__center
202
203 @center.setter
206
207 @property
209 """Read-write, width of the rectangle :: float | int"""
210 return self.right - self.left
211
212 @width.setter
215
216 @property
218 """Read-write, height of the rectangle :: float | int"""
219 return self.bottom - self.top
220
221 @height.setter
224
225 @property
227 """Read-write, size of the rectangle :: bound Vector"""
228 return self.__size
229
230 @size.setter
231 - def size(self, value):
233
234 @property
236 """Read-write, left edge of rectangle :: float | int"""
237 return self.__left
238
239 @left.setter
240 - def left(self, value):
242
243 @property
245 """Read-write, top edge of rectangle :: float | int"""
246 return self.__top
247
248 @top.setter
249 - def top(self, value):
251
252 @property
254 """Read-write, right edge of rectangle :: float | int"""
255 return self.__right
256
257 @right.setter
260
261 @property
263 """Read-write, bottom edge of rectangle :: float | int"""
264 return self.__bottom
265
266 @bottom.setter
268 self.__bottom = value
269
270
271
272
273 @property
275 """Read-write, top-left corner :: bound Vector"""
276 return self.__top_left
277
278 @top_left.setter
280 return self.__top_left.assign(value)
281
282 @property
284 """Read-write, top-right corner :: bound Vector"""
285 return self.__top_right
286
287 @top_right.setter
289 return self.__top_right.assign(value)
290
291 @property
293 """Read-write, bottom-left corner :: bound Vector"""
294 return self.__bottom_left
295
296 @bottom_left.setter
298 return self.__bottom_left.assign(value)
299
300 @property
302 """Read-write, bottom-right corner :: bound Vector"""
303 return self.__bottom_right
304
305 @bottom_right.setter
307 return self.__bottom_right.assign(value)
308
310 """
311 Returns `True` if `v` is inside the rectangle.
312
313 Parameters:
314
315 `v` :: Vector
316 """
317 x,y = v.xy
318 return (self.left <= x <= self.right and
319 self.top <= y <= self.bottom)
320
322 """
323 Returns `True` if `rect` overlaps with this rectangle.
324
325 Parameters:
326
327 `rect` :: Rectangle
328 """
329 return (self.right > rect.left and self.left < rect.right and
330 self.top < rect.bottom and self.bottom > rect.top)
331
337
344
345 @overloaded((
346 Overload(__inflate_number,
347 Param("n", NumberType)),
348 Overload(__inflate_vector,
349 Param("v"))))
351 """
352 Inflate the rectangle
353
354 Overloaded, parameters:
355
356 :a:
357 n :: number
358 Extend all sides by n points
359 :b:
360 v :: Vector
361 extend left and right sides by v.x and top and bottom sides by
362 v.y
363 """
364
366 """
367 Move the top_left corner to `v`, without changing size
368
369 Parameters:
370
371 `v` :: Vector
372 the spot to move to
373 """
374 bottom_right = v + self.size
375 (self.left, self.top) = v.xy
376 (self.right, self.bottom) = bottom_right.xy
377
379 """
380 Move the top_left corner by `v`, without changing size
381
382 Parameters:
383
384 `v` :: Vector
385 the amount to move by
386 """
387 self.left += v.x
388 self.right += v.x
389 self.top += v.y
390 self.bottom += v.y
391
393 return "<%s (%s,%s)-(%s,%s)>" % (self.__class__.__name__,
394 self.left, self.top,
395 self.right, self.bottom)
396
401
402
403
404