rect.py 2 KB
Newer Older
Guido van Rossum's avatar
Guido van Rossum committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
# Module 'rect'.
#
# Operations on rectangles.
# There is some normalization: all results return the object 'empty'
# if their result would contain no points.


# Exception.
#
error = 'rect.error'


# The empty rectangle.
#
empty = (0, 0), (0, 0)


# Check if a rectangle is empty.
#
20 21
def is_empty(r):
	(left, top), (right, bottom) = r
Guido van Rossum's avatar
Guido van Rossum committed
22 23 24 25 26 27 28 29 30 31 32
	return left >= right or top >= bottom


# Compute the intersection or two or more rectangles.
# This works with a list or tuple argument.
#
def intersect(list):
	if not list: raise error, 'intersect called with empty list'
	if is_empty(list[0]): return empty
	(left, top), (right, bottom) = list[0]
	for rect in list[1:]:
33 34 35 36 37 38 39
		if is_empty(rect):
			return empty
		(l, t), (r, b) = rect
		if left < l: left = l
		if top < t: top = t
		if right > r: right = r
		if bottom > b: bottom = b
40
		if is_empty(((left, top), (right, bottom))):
41
			return empty
Guido van Rossum's avatar
Guido van Rossum committed
42 43 44 45 46 47 48
	return (left, top), (right, bottom)


# Compute the smallest rectangle containing all given rectangles.
# This works with a list or tuple argument.
#
def union(list):
49
	(left, top), (right, bottom) = list[0]
Guido van Rossum's avatar
Guido van Rossum committed
50
	for (l, t), (r, b) in list[1:]:
51
		if not is_empty(((l, t), (r, b))):
Guido van Rossum's avatar
Guido van Rossum committed
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
			if l < left: left = l
			if t < top: top = t
			if r > right: right = r
			if b > bottom: bottom = b
	res = (left, top), (right, bottom)
	if is_empty(res):
		return empty
	return res


# Check if a point is in a rectangle.
#
def pointinrect((h, v), ((left, top), (right, bottom))):
	return left <= h < right and top <= v < bottom


# Return a rectangle that is dh, dv inside another
#
def inset(((left, top), (right, bottom)), (dh, dv)):
	left = left + dh
	top = top + dv
	right = right - dh
	bottom = bottom - dv
	r = (left, top), (right, bottom)
	if is_empty(r):
		return empty
	else:
		return r


# Conversions between rectangles and 'geometry tuples',
# given as origin (h, v) and dimensions (width, height).
#
def rect2geom((left, top), (right, bottom)):
	return (left, top), (right-left, bottom-top)

def geom2rect((h, v), (width, height)):
	return (h, v), (h+width, v+height)