2 # -*- coding: ISO-8859-1 -*-
5 # Copyright (C) 2002-2005 Jörg Lehmann <joergl@users.sourceforge.net>
6 # Copyright (C) 2002-2004 André Wobst <wobsta@users.sourceforge.net>
8 # This file is part of PyX (http://pyx.sourceforge.net/).
10 # PyX is free software; you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by
12 # the Free Software Foundation; either version 2 of the License, or
13 # (at your option) any later version.
15 # PyX is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 # GNU General Public License for more details.
20 # You should have received a copy of the GNU General Public License
21 # along with PyX; if not, write to the Free Software
22 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
28 # classes representing bounding boxes
33 """class for bounding boxes
35 This variant requires points in the constructor, and is used for internal
38 def __init__(self
, llx_pt
, lly_pt
, urx_pt
, ury_pt
):
44 def __add__(self
, other
):
46 return bbox_pt(min(self
.llx_pt
, other
.llx_pt
), min(self
.lly_pt
, other
.lly_pt
),
47 max(self
.urx_pt
, other
.urx_pt
), max(self
.ury_pt
, other
.ury_pt
))
49 def __iadd__(self
, other
):
50 """join two bboxes inplace"""
51 self
.llx_pt
= min(self
.llx_pt
, other
.llx_pt
)
52 self
.lly_pt
= min(self
.lly_pt
, other
.lly_pt
)
53 self
.urx_pt
= max(self
.urx_pt
, other
.urx_pt
)
54 self
.ury_pt
= max(self
.ury_pt
, other
.ury_pt
)
57 def __mul__(self
, other
):
58 """return intersection of two bboxes"""
59 return bbox_pt(max(self
.llx_pt
, other
.llx_pt
), max(self
.lly_pt
, other
.lly_pt
),
60 min(self
.urx_pt
, other
.urx_pt
), min(self
.ury_pt
, other
.ury_pt
))
62 def __imul__(self
, other
):
63 """intersect two bboxes in place"""
64 self
.llx_pt
= max(self
.llx_pt
, other
.llx_pt
)
65 self
.lly_pt
= max(self
.lly_pt
, other
.lly_pt
)
66 self
.urx_pt
= min(self
.urx_pt
, other
.urx_pt
)
67 self
.ury_pt
= min(self
.ury_pt
, other
.ury_pt
)
70 def lowrestuple_pt(self
):
71 return (math
.floor(self
.llx_pt
), math
.floor(self
.lly_pt
),
72 math
.ceil(self
.urx_pt
), math
.ceil(self
.ury_pt
))
74 def highrestuple_pt(self
):
75 return (self
.llx_pt
, self
.lly_pt
, self
.urx_pt
, self
.ury_pt
)
77 def intersects(self
, other
):
78 """check, if two bboxes intersect eachother"""
79 return not (self
.llx_pt
> other
.urx_pt
or
80 self
.lly_pt
> other
.ury_pt
or
81 self
.urx_pt
< other
.llx_pt
or
82 self
.ury_pt
< other
.lly_pt
)
84 def transform(self
, trafo
):
85 """transform bbox in place by trafo"""
86 # we have to transform all four corner points of the bbox
87 llx_pt
, lly_pt
= trafo
._apply
(self
.llx_pt
, self
.lly_pt
)
88 lrx
, lry
= trafo
._apply
(self
.urx_pt
, self
.lly_pt
)
89 urx_pt
, ury_pt
= trafo
._apply
(self
.urx_pt
, self
.ury_pt
)
90 ulx
, uly
= trafo
._apply
(self
.llx_pt
, self
.ury_pt
)
92 # Now, by sorting, we obtain the lower left and upper right corner
93 # of the new bounding box.
94 self
.llx_pt
= min(llx_pt
, lrx
, urx_pt
, ulx
)
95 self
.lly_pt
= min(lly_pt
, lry
, ury_pt
, uly
)
96 self
.urx_pt
= max(llx_pt
, lrx
, urx_pt
, ulx
)
97 self
.ury_pt
= max(lly_pt
, lry
, ury_pt
, uly
)
99 def transformed(self
, trafo
):
100 """return bbox transformed by trafo"""
101 # we have to transform all four corner points of the bbox
102 llx_pt
, lly_pt
= trafo
._apply
(self
.llx_pt
, self
.lly_pt
)
103 lrx
, lry
= trafo
._apply
(self
.urx_pt
, self
.lly_pt
)
104 urx_pt
, ury_pt
= trafo
._apply
(self
.urx_pt
, self
.ury_pt
)
105 ulx
, uly
= trafo
._apply
(self
.llx_pt
, self
.ury_pt
)
107 # Now, by sorting, we obtain the lower left and upper right corner
108 # of the new bounding box.
109 return bbox_pt(min(llx_pt
, lrx
, urx_pt
, ulx
), min(lly_pt
, lry
, ury_pt
, uly
),
110 max(llx_pt
, lrx
, urx_pt
, ulx
), max(lly_pt
, lry
, ury_pt
, uly
))
112 def enlarge(self
, all
=0, bottom
=None, left
=None, top
=None, right
=None):
113 """enlarge bbox in place
115 all is used, if bottom, left, top and/or right are not given.
118 bottom_pt
= left_pt
= top_pt
= right_pt
= unit
.topt(all
)
119 if bottom
is not None:
120 bottom_pt
= unit
.topt(bottom
)
122 left_pt
= unit
.topt(left
)
124 top_pt
= unit
.topt(top
)
125 if right
is not None:
126 right_pt
= unit
.topt(right
)
127 self
.llx_pt
-= left_pt
128 self
.lly_pt
-= bottom_pt
129 self
.urx_pt
+= right_pt
130 self
.ury_pt
+= top_pt
132 def enlarged(self
, all
=0, bottom
=None, left
=None, top
=None, right
=None):
133 """return bbox enlarged
135 all is used, if bottom, left, top and/or right are not given.
138 bottom_pt
= left_pt
= top_pt
= right_pt
= unit
.topt(all
)
139 if bottom
is not None:
140 bottom_pt
= unit
.topt(bottom
)
142 left_pt
= unit
.topt(left
)
144 top_pt
= unit
.topt(top
)
145 if right
is not None:
146 right_pt
= unit
.topt(right
)
147 return bbox_pt(self
.llx_pt
-left_pt
, self
.lly_pt
-bottom_pt
, self
.urx_pt
+right_pt
, self
.ury_pt
+top_pt
)
150 """return rectangle corresponding to bbox"""
152 return path
.rect_pt(self
.llx_pt
, self
.lly_pt
, self
.urx_pt
-self
.llx_pt
, self
.ury_pt
-self
.lly_pt
)
157 """return height of bbox in pts"""
158 return self
.ury_pt
-self
.lly_pt
161 """return width of bbox in pts"""
162 return self
.urx_pt
-self
.llx_pt
165 """return top coordinate of bbox in pts"""
169 """return bottom coordinate of bbox in pts"""
173 """return left coordinate of bbox in pts"""
177 """return right coordinate of bbox in pts"""
181 """return coordinates of the center of the bbox in pts"""
182 return 0.5 * (self
.llx_pt
+self
.urx_pt
), 0.5 * (self
.lly_pt
+self
.ury_pt
)
185 """return height of bbox"""
186 return self
.height_pt() * unit
.t_pt
189 """return width of bbox"""
190 return self
.width_pt() * unit
.t_pt
193 """return top coordinate of bbox"""
194 return self
.ury_pt
* unit
.t_pt
197 """return bottom coordinate of bbox"""
198 return self
.lly_pt
* unit
.t_pt
201 """return left coordinate of bbox"""
202 return self
.llx_pt
* unit
.t_pt
205 """return right coordinate of bbox"""
206 return self
.urx_pt
* unit
.t_pt
209 """return coordinates of the center of the bbox"""
210 centerx_pt
, centery_pt
= self
.center_pt()
211 return centerx_pt
* unit
.t_pt
, centery_pt
* unit
.t_pt
216 """class for bounding boxes"""
218 def __init__(self
, llx_pt
, lly_pt
, urx_pt
, ury_pt
):
219 llx_pt
= unit
.topt(llx_pt
)
220 lly_pt
= unit
.topt(lly_pt
)
221 urx_pt
= unit
.topt(urx_pt
)
222 ury_pt
= unit
.topt(ury_pt
)
223 bbox_pt
.__init
__(self
, llx_pt
, lly_pt
, urx_pt
, ury_pt
)