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
)
71 return bbox_pt(self
.llx_pt
, self
.lly_pt
, self
.urx_pt
, self
.ury_pt
)
73 def lowrestuple_pt(self
):
74 return (math
.floor(self
.llx_pt
), math
.floor(self
.lly_pt
),
75 math
.ceil(self
.urx_pt
), math
.ceil(self
.ury_pt
))
77 def highrestuple_pt(self
):
78 return (self
.llx_pt
, self
.lly_pt
, self
.urx_pt
, self
.ury_pt
)
80 def intersects(self
, other
):
81 """check, if two bboxes intersect eachother"""
82 return not (self
.llx_pt
> other
.urx_pt
or
83 self
.lly_pt
> other
.ury_pt
or
84 self
.urx_pt
< other
.llx_pt
or
85 self
.ury_pt
< other
.lly_pt
)
87 def includepoint_pt(self
, x_pt
, y_pt
):
88 self
.llx_pt
= min(self
.llx_pt
, x_pt
)
89 self
.lly_pt
= min(self
.lly_pt
, y_pt
)
90 self
.urx_pt
= max(self
.urx_pt
, x_pt
)
91 self
.ury_pt
= max(self
.ury_pt
, y_pt
)
93 def transform(self
, trafo
):
94 """transform bbox in place by trafo"""
95 # we have to transform all four corner points of the bbox
96 llx_pt
, lly_pt
= trafo
.apply_pt(self
.llx_pt
, self
.lly_pt
)
97 lrx_pt
, lry_pt
= trafo
.apply_pt(self
.urx_pt
, self
.lly_pt
)
98 urx_pt
, ury_pt
= trafo
.apply_pt(self
.urx_pt
, self
.ury_pt
)
99 ulx_pt
, uly_pt
= trafo
.apply_pt(self
.llx_pt
, self
.ury_pt
)
101 # Now, by sorting, we obtain the lower left and upper right corner
102 # of the new bounding box.
103 self
.llx_pt
= min(llx_pt
, lrx_pt
, urx_pt
, ulx_pt
)
104 self
.lly_pt
= min(lly_pt
, lry_pt
, ury_pt
, uly_pt
)
105 self
.urx_pt
= max(llx_pt
, lrx_pt
, urx_pt
, ulx_pt
)
106 self
.ury_pt
= max(lly_pt
, lry_pt
, ury_pt
, uly_pt
)
108 def transformed(self
, trafo
):
109 """return bbox transformed by trafo"""
110 # we have to transform all four corner points of the bbox
111 llx_pt
, lly_pt
= trafo
.apply_pt(self
.llx_pt
, self
.lly_pt
)
112 lrx_pt
, lry_pt
= trafo
.apply_pt(self
.urx_pt
, self
.lly_pt
)
113 urx_pt
, ury_pt
= trafo
.apply_pt(self
.urx_pt
, self
.ury_pt
)
114 ulx_pt
, uly_pt
= trafo
.apply_pt(self
.llx_pt
, self
.ury_pt
)
116 # Now, by sorting, we obtain the lower left and upper right corner
117 # of the new bounding box.
118 return bbox_pt(min(llx_pt
, lrx_pt
, urx_pt
, ulx_pt
), min(lly_pt
, lry_pt
, ury_pt
, uly_pt
),
119 max(llx_pt
, lrx_pt
, urx_pt
, ulx_pt
), max(lly_pt
, lry_pt
, ury_pt
, uly_pt
))
121 def enlarge(self
, all
=0, bottom
=None, left
=None, top
=None, right
=None):
122 """enlarge bbox in place
124 all is used, if bottom, left, top and/or right are not given.
127 bottom_pt
= left_pt
= top_pt
= right_pt
= unit
.topt(all
)
128 if bottom
is not None:
129 bottom_pt
= unit
.topt(bottom
)
131 left_pt
= unit
.topt(left
)
133 top_pt
= unit
.topt(top
)
134 if right
is not None:
135 right_pt
= unit
.topt(right
)
136 self
.llx_pt
-= left_pt
137 self
.lly_pt
-= bottom_pt
138 self
.urx_pt
+= right_pt
139 self
.ury_pt
+= top_pt
141 def enlarged(self
, all
=0, bottom
=None, left
=None, top
=None, right
=None):
142 """return bbox enlarged
144 all is used, if bottom, left, top and/or right are not given.
147 bottom_pt
= left_pt
= top_pt
= right_pt
= unit
.topt(all
)
148 if bottom
is not None:
149 bottom_pt
= unit
.topt(bottom
)
151 left_pt
= unit
.topt(left
)
153 top_pt
= unit
.topt(top
)
154 if right
is not None:
155 right_pt
= unit
.topt(right
)
156 return bbox_pt(self
.llx_pt
-left_pt
, self
.lly_pt
-bottom_pt
, self
.urx_pt
+right_pt
, self
.ury_pt
+top_pt
)
159 """return rectangle corresponding to bbox"""
161 return path
.rect_pt(self
.llx_pt
, self
.lly_pt
, self
.urx_pt
-self
.llx_pt
, self
.ury_pt
-self
.lly_pt
)
166 """return height of bbox in pts"""
167 return self
.ury_pt
-self
.lly_pt
170 """return width of bbox in pts"""
171 return self
.urx_pt
-self
.llx_pt
174 """return top coordinate of bbox in pts"""
178 """return bottom coordinate of bbox in pts"""
182 """return left coordinate of bbox in pts"""
186 """return right coordinate of bbox in pts"""
190 """return coordinates of the center of the bbox in pts"""
191 return 0.5 * (self
.llx_pt
+self
.urx_pt
), 0.5 * (self
.lly_pt
+self
.ury_pt
)
194 """return height of bbox"""
195 return self
.height_pt() * unit
.t_pt
198 """return width of bbox"""
199 return self
.width_pt() * unit
.t_pt
202 """return top coordinate of bbox"""
203 return self
.ury_pt
* unit
.t_pt
206 """return bottom coordinate of bbox"""
207 return self
.lly_pt
* unit
.t_pt
210 """return left coordinate of bbox"""
211 return self
.llx_pt
* unit
.t_pt
214 """return right coordinate of bbox"""
215 return self
.urx_pt
* unit
.t_pt
218 """return coordinates of the center of the bbox"""
219 centerx_pt
, centery_pt
= self
.center_pt()
220 return centerx_pt
* unit
.t_pt
, centery_pt
* unit
.t_pt
225 """class for bounding boxes"""
227 def __init__(self
, llx_pt
, lly_pt
, urx_pt
, ury_pt
):
228 llx_pt
= unit
.topt(llx_pt
)
229 lly_pt
= unit
.topt(lly_pt
)
230 urx_pt
= unit
.topt(urx_pt
)
231 ury_pt
= unit
.topt(ury_pt
)
232 bbox_pt
.__init
__(self
, llx_pt
, lly_pt
, urx_pt
, ury_pt
)