extern variables and functions in data.data; testsuite enhancements)
[PyX/mjg.git] / pyx / bbox.py
blob4ae73c943faf3bfbb5ebf6fc499a4ce3061d8154
1 #!/usr/bin/env python
4 # Copyright (C) 2002 Jörg Lehmann <joergl@users.sourceforge.net>
5 # Copyright (C) 2002 André Wobst <wobsta@users.sourceforge.net>
7 # This file is part of PyX (http://pyx.sourceforge.net/).
9 # PyX is free software; you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation; either version 2 of the License, or
12 # (at your option) any later version.
14 # PyX is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
19 # You should have received a copy of the GNU General Public License
20 # along with PyX; if not, write to the Free Software
21 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 import unit
25 # helper routine for bbox manipulations
27 def _nmin(x, y):
28 """minimum of two values, where None represents +infinity, not -infinity as
29 in standard min implementation of python"""
30 if x is None: return y
31 if y is None: return x
32 return min(x,y)
35 # class representing bounding boxes
38 class bbox:
40 """class for bounding boxes"""
42 def __init__(self, llx=None, lly=None, urx=None, ury=None):
43 self.llx=llx
44 self.lly=lly
45 self.urx=urx
46 self.ury=ury
48 def __add__(self, other):
49 """join two bboxes"""
51 return bbox(_nmin(self.llx, other.llx), _nmin(self.lly, other.lly),
52 max(self.urx, other.urx), max(self.ury, other.ury))
54 def __mul__(self, other):
55 """return intersection of two bboxes"""
57 return bbox(max(self.llx, other.llx), max(self.lly, other.lly),
58 _nmin(self.urx, other.urx), _nmin(self.ury, other.ury))
60 def __str__(self):
61 return "%s %s %s %s" % (self.llx, self.lly, self.urx, self.ury)
63 def write(self, file):
64 file.write("%%%%BoundingBox: %d %d %d %d\n" %
65 (self.llx, self.lly, self.urx, self.ury))
66 # TODO: add HighResBBox
68 def intersects(self, other):
69 """check, if two bboxes intersect eachother"""
71 return not (self.llx > other.urx or
72 self.lly > other.ury or
73 self.urx < other.llx or
74 self.ury < other.lly)
76 def transform(self, trafo):
77 """return bbox transformed by trafo"""
78 # we have to transform all four corner points of the bbox
79 (llx, lly)=trafo._apply(self.llx, self.lly)
80 (lrx, lry)=trafo._apply(self.urx, self.lly)
81 (urx, ury)=trafo._apply(self.urx, self.ury)
82 (ulx, uly)=trafo._apply(self.llx, self.ury)
84 # now, by sorting, we obtain the lower left and upper right corner
85 # of the new bounding box.
87 return bbox(min(llx, lrx, urx, ulx), min(lly, lry, ury, uly),
88 max(llx, lrx, urx, ulx), max(lly, lry, ury, uly))
90 def enhance(self, size):
91 """return bbox enhanced in all directions by size"""
92 size = unit.topt(unit.length(size, default_type="v"))
93 return bbox(self.llx-size, self.lly-size,
94 self.urx+size, self.ury+size)
96 def rect(self):
97 """return rectangle corresponding to bbox"""
98 import path
99 return path._rect(self.llx, self.lly, self.urx-self.llx, self.ury-self.lly)