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 includepoint_pt(self
, x_pt
, y_pt
):
85 self
.llx_pt
= min(self
.llx_pt
, x_pt
)
86 self
.lly_pt
= min(self
.lly_pt
, y_pt
)
87 self
.urx_pt
= max(self
.urx_pt
, x_pt
)
88 self
.ury_pt
= max(self
.ury_pt
, y_pt
)
90 def transform(self
, trafo
):
91 """transform bbox in place by trafo"""
92 # we have to transform all four corner points of the bbox
93 llx_pt
, lly_pt
= trafo
.apply_pt(self
.llx_pt
, self
.lly_pt
)
94 lrx
, lry
= trafo
.apply_pt(self
.urx_pt
, self
.lly_pt
)
95 urx_pt
, ury_pt
= trafo
.apply_pt(self
.urx_pt
, self
.ury_pt
)
96 ulx
, uly
= trafo
.apply_pt(self
.llx_pt
, self
.ury_pt
)
98 # Now, by sorting, we obtain the lower left and upper right corner
99 # of the new bounding box.
100 self
.llx_pt
= min(llx_pt
, lrx
, urx_pt
, ulx
)
101 self
.lly_pt
= min(lly_pt
, lry
, ury_pt
, uly
)
102 self
.urx_pt
= max(llx_pt
, lrx
, urx_pt
, ulx
)
103 self
.ury_pt
= max(lly_pt
, lry
, ury_pt
, uly
)
105 def transformed(self
, trafo
):
106 """return bbox transformed by trafo"""
107 # we have to transform all four corner points of the bbox
108 llx_pt
, lly_pt
= trafo
.apply_pt(self
.llx_pt
, self
.lly_pt
)
109 lrx
, lry
= trafo
.apply_pt(self
.urx_pt
, self
.lly_pt
)
110 urx_pt
, ury_pt
= trafo
.apply_pt(self
.urx_pt
, self
.ury_pt
)
111 ulx
, uly
= trafo
.apply_pt(self
.llx_pt
, self
.ury_pt
)
113 # Now, by sorting, we obtain the lower left and upper right corner
114 # of the new bounding box.
115 return bbox_pt(min(llx_pt
, lrx
, urx_pt
, ulx
), min(lly_pt
, lry
, ury_pt
, uly
),
116 max(llx_pt
, lrx
, urx_pt
, ulx
), max(lly_pt
, lry
, ury_pt
, uly
))
118 def enlarge(self
, all
=0, bottom
=None, left
=None, top
=None, right
=None):
119 """enlarge bbox in place
121 all is used, if bottom, left, top and/or right are not given.
124 bottom_pt
= left_pt
= top_pt
= right_pt
= unit
.topt(all
)
125 if bottom
is not None:
126 bottom_pt
= unit
.topt(bottom
)
128 left_pt
= unit
.topt(left
)
130 top_pt
= unit
.topt(top
)
131 if right
is not None:
132 right_pt
= unit
.topt(right
)
133 self
.llx_pt
-= left_pt
134 self
.lly_pt
-= bottom_pt
135 self
.urx_pt
+= right_pt
136 self
.ury_pt
+= top_pt
138 def enlarged(self
, all
=0, bottom
=None, left
=None, top
=None, right
=None):
139 """return bbox enlarged
141 all is used, if bottom, left, top and/or right are not given.
144 bottom_pt
= left_pt
= top_pt
= right_pt
= unit
.topt(all
)
145 if bottom
is not None:
146 bottom_pt
= unit
.topt(bottom
)
148 left_pt
= unit
.topt(left
)
150 top_pt
= unit
.topt(top
)
151 if right
is not None:
152 right_pt
= unit
.topt(right
)
153 return bbox_pt(self
.llx_pt
-left_pt
, self
.lly_pt
-bottom_pt
, self
.urx_pt
+right_pt
, self
.ury_pt
+top_pt
)
156 """return rectangle corresponding to bbox"""
158 return path
.rect_pt(self
.llx_pt
, self
.lly_pt
, self
.urx_pt
-self
.llx_pt
, self
.ury_pt
-self
.lly_pt
)
163 """return height of bbox in pts"""
164 return self
.ury_pt
-self
.lly_pt
167 """return width of bbox in pts"""
168 return self
.urx_pt
-self
.llx_pt
171 """return top coordinate of bbox in pts"""
175 """return bottom coordinate of bbox in pts"""
179 """return left coordinate of bbox in pts"""
183 """return right coordinate of bbox in pts"""
187 """return coordinates of the center of the bbox in pts"""
188 return 0.5 * (self
.llx_pt
+self
.urx_pt
), 0.5 * (self
.lly_pt
+self
.ury_pt
)
191 """return height of bbox"""
192 return self
.height_pt() * unit
.t_pt
195 """return width of bbox"""
196 return self
.width_pt() * unit
.t_pt
199 """return top coordinate of bbox"""
200 return self
.ury_pt
* unit
.t_pt
203 """return bottom coordinate of bbox"""
204 return self
.lly_pt
* unit
.t_pt
207 """return left coordinate of bbox"""
208 return self
.llx_pt
* unit
.t_pt
211 """return right coordinate of bbox"""
212 return self
.urx_pt
* unit
.t_pt
215 """return coordinates of the center of the bbox"""
216 centerx_pt
, centery_pt
= self
.center_pt()
217 return centerx_pt
* unit
.t_pt
, centery_pt
* unit
.t_pt
222 """class for bounding boxes"""
224 def __init__(self
, llx_pt
, lly_pt
, urx_pt
, ury_pt
):
225 llx_pt
= unit
.topt(llx_pt
)
226 lly_pt
= unit
.topt(lly_pt
)
227 urx_pt
= unit
.topt(urx_pt
)
228 ury_pt
= unit
.topt(ury_pt
)
229 bbox_pt
.__init
__(self
, llx_pt
, lly_pt
, urx_pt
, ury_pt
)