]> git.saurik.com Git - wxWidgets.git/blob - contrib/src/canvas/bbox.cpp
Trying to understand wxCanvas.
[wxWidgets.git] / contrib / src / canvas / bbox.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: bbox.cpp
3 // Author: Klaas Holwerda
4 // Created: XX/XX/XX
5 // Copyright: 2000 (c) Klaas Holwerda
6 // Licence: wxWindows Licence
7 /////////////////////////////////////////////////////////////////////////////
8
9 #ifdef __GNUG__
10 #pragma implementation "bbox.cpp"
11 #endif
12
13 // For compilers that support precompilation, includes "wx/wx.h".
14 #include "wx/wxprec.h"
15
16 #ifdef __BORLANDC__
17 #pragma hdrstop
18 #endif
19
20 #include "wx/canvas/bbox.h"
21
22 wxBoundingBox::wxBoundingBox()
23 {
24 m_minx = m_miny = m_maxx = m_maxy = 0.0;
25 m_validbbox = FALSE;
26 }
27
28
29 wxBoundingBox::wxBoundingBox(wxBoundingBox &other)
30 {
31 m_minx = other.m_minx;
32 m_miny = other.m_miny;
33 m_maxx = other.m_maxx;
34 m_maxy = other.m_maxy;
35 m_validbbox= other.m_validbbox;
36 }
37
38
39 wxBoundingBox::wxBoundingBox(const wxPoint2DDouble& a)
40 {
41 m_minx = a.m_x;
42 m_maxx = a.m_x;
43 m_miny = a.m_y;
44 m_maxy = a.m_y;
45 m_validbbox = TRUE;
46 }
47
48 wxBoundingBox::wxBoundingBox(double xmin, double ymin, double xmax, double ymax)
49 {
50 m_minx = xmin;
51 m_miny = ymin;
52 m_maxx = xmax;
53 m_maxy = ymax;
54 m_validbbox = TRUE;
55 }
56
57 // This function checks if two bboxes intersect
58 bool wxBoundingBox::And(wxBoundingBox *_bbox, double Marge)
59 {
60 assert (m_validbbox == TRUE);
61 assert (_bbox->GetValid());
62 m_minx = wxMax(m_minx, _bbox->m_minx);
63 m_maxx = wxMin(m_maxx, _bbox->m_maxx);
64 m_miny = wxMax(m_miny, _bbox->m_miny);
65 m_maxy = wxMin(m_maxy, _bbox->m_maxy);
66 return (bool)
67 (
68 ((m_minx - Marge) < (m_maxx + Marge)) &&
69 ((m_miny - Marge) < (m_maxy + Marge))
70 );
71 }
72
73 // Shrink the boundingbox with the given marge
74 void wxBoundingBox::Shrink(const double Marge)
75 {
76 assert (m_validbbox == TRUE);
77
78 m_minx += Marge;
79 m_maxx -= Marge;
80 m_miny += Marge;
81 m_maxy -= Marge;
82 }
83
84
85 // Expand the boundingbox with another boundingbox
86 void wxBoundingBox::Expand(const wxBoundingBox &other)
87 {
88 if (!m_validbbox)
89 {
90 *this=other;
91 }
92 else
93 {
94 m_minx = wxMin(m_minx, other.m_minx);
95 m_maxx = wxMax(m_maxx, other.m_maxx);
96 m_miny = wxMin(m_miny, other.m_miny);
97 m_maxy = wxMax(m_maxy, other.m_maxy);
98 }
99 }
100
101
102 // Expand the boundingbox with a point
103 void wxBoundingBox::Expand(const wxPoint2DDouble& a_point)
104 {
105 if (!m_validbbox)
106 {
107 m_minx = m_maxx = a_point.m_x;
108 m_miny = m_maxy = a_point.m_y;
109 m_validbbox=TRUE;
110 }
111 else
112 {
113 m_minx = wxMin(m_minx, a_point.m_x);
114 m_maxx = wxMax(m_maxx, a_point.m_x);
115 m_miny = wxMin(m_miny, a_point.m_y);
116 m_maxy = wxMax(m_maxy, a_point.m_y);
117 }
118 }
119
120 // Expand the boundingbox with a point
121 void wxBoundingBox::Expand(double x,double y)
122 {
123 if (!m_validbbox)
124 {
125 m_minx = m_maxx = x;
126 m_miny = m_maxy = y;
127 m_validbbox=TRUE;
128 }
129 else
130 {
131 m_minx = wxMin(m_minx, x);
132 m_maxx = wxMax(m_maxx, x);
133 m_miny = wxMin(m_miny, y);
134 m_maxy = wxMax(m_maxy, y);
135 }
136 }
137
138
139 // Expand the boundingbox with two points
140 void wxBoundingBox::Expand(const wxPoint2DDouble& a, const wxPoint2DDouble& b)
141 {
142 Expand(a);
143 Expand(b);
144 }
145
146 // Enlarge the boundingbox with the given marge
147 void wxBoundingBox::EnLarge(const double marge)
148 {
149 if (!m_validbbox)
150 {
151 m_minx = m_maxx = marge;
152 m_miny = m_maxy = marge;
153 m_validbbox=TRUE;
154 }
155 else
156 {
157 m_minx -= marge;
158 m_maxx += marge;
159 m_miny -= marge;
160 m_maxy += marge;
161 }
162 }
163
164 // Calculates if two boundingboxes intersect. If so, the function returns _ON.
165 // If they do not intersect, two scenario's are possible:
166 // other is outside this -> return _OUT
167 // other is inside this -> return _IN
168 OVERLAP wxBoundingBox::Intersect(wxBoundingBox &other, double Marge)
169 {
170 assert (m_validbbox == TRUE);
171
172 // other boundingbox must exist
173 assert (&other);
174
175 if (((m_minx - Marge) > (other.m_maxx + Marge)) ||
176 ((m_maxx + Marge) < (other.m_minx - Marge)) ||
177 ((m_maxy + Marge) < (other.m_miny - Marge)) ||
178 ((m_miny - Marge) > (other.m_maxy + Marge)))
179 return _OUT;
180
181 // Check if other.bbox is inside this bbox
182 if ((m_minx <= other.m_minx) &&
183 (m_maxx >= other.m_maxx) &&
184 (m_maxy >= other.m_maxy) &&
185 (m_miny <= other.m_miny))
186 return _IN;
187
188 // Boundingboxes intersect
189 return _ON;
190 }
191
192
193 // Checks if a line intersects the boundingbox
194 bool wxBoundingBox::LineIntersect(const wxPoint2DDouble& begin, const wxPoint2DDouble& end )
195 {
196 assert (m_validbbox == TRUE);
197
198 return (bool)
199 !(((begin.m_y > m_maxy) && (end.m_y > m_maxy)) ||
200 ((begin.m_y < m_miny) && (end.m_y < m_miny)) ||
201 ((begin.m_x > m_maxx) && (end.m_x > m_maxx)) ||
202 ((begin.m_x < m_minx) && (end.m_x < m_minx)));
203 }
204
205
206 // Is the given point in the boundingbox ??
207 bool wxBoundingBox::PointInBox(double x, double y, double Marge)
208 {
209 assert (m_validbbox == TRUE);
210
211 if ( x >= (m_minx - Marge) && x <= (m_maxx + Marge) &&
212 y >= (m_miny - Marge) && y <= (m_maxy + Marge) )
213 return TRUE;
214 return FALSE;
215 }
216
217
218 //
219 // Is the given point in the boundingbox ??
220 //
221 bool wxBoundingBox::PointInBox(const wxPoint2DDouble& a, double Marge)
222 {
223 assert (m_validbbox == TRUE);
224
225 return PointInBox(a.m_x, a.m_y, Marge);
226 }
227
228
229 wxPoint2DDouble wxBoundingBox::GetMin()
230 {
231 assert (m_validbbox == TRUE);
232
233 return wxPoint2DDouble(m_minx, m_miny);
234 }
235
236
237 wxPoint2DDouble wxBoundingBox::GetMax()
238 {
239 assert (m_validbbox == TRUE);
240
241 return wxPoint2DDouble(m_maxx, m_maxy);
242 }
243
244 bool wxBoundingBox::GetValid() const
245 {
246 return m_validbbox;
247 }
248
249 void wxBoundingBox::SetMin(double px, double py)
250 {
251 m_minx = px;
252 m_miny = py;
253 if (!m_validbbox)
254 {
255 m_maxx = px;
256 m_maxy = py;
257 m_validbbox = TRUE;
258 }
259 }
260
261 void wxBoundingBox::SetMax(double px, double py)
262 {
263 m_maxx = px;
264 m_maxy = py;
265 if (!m_validbbox)
266 {
267 m_minx = px;
268 m_miny = py;
269 m_validbbox = TRUE;
270 }
271 }
272
273 void wxBoundingBox::SetValid(bool value)
274 {
275 m_validbbox = value;
276 }
277
278 // adds an offset to the boundingbox
279 // usage : a_boundingbox.Translate(a_point);
280 void wxBoundingBox::Translate(wxPoint2DDouble& offset)
281 {
282 assert (m_validbbox == TRUE);
283
284 m_minx += offset.m_x;
285 m_maxx += offset.m_x;
286 m_miny += offset.m_y;
287 m_maxy += offset.m_y;
288 }
289
290
291 // clears the bounding box settings
292 void wxBoundingBox::Reset()
293 {
294 m_minx = 0.0;
295 m_maxx = 0.0;
296 m_miny = 0.0;
297 m_maxy = 0.0;
298 m_validbbox = FALSE;
299 }
300
301
302 void wxBoundingBox::SetBoundingBox(const wxPoint2DDouble& a_point)
303 {
304 m_minx = a_point.m_x;
305 m_maxx = a_point.m_x;
306 m_miny = a_point.m_y;
307 m_maxy = a_point.m_y;
308 }
309
310
311 // Expands the boundingbox with the given point
312 // usage : a_boundingbox = a_boundingbox + pointer_to_an_offset;
313 wxBoundingBox& wxBoundingBox::operator+(wxBoundingBox &other)
314 {
315 assert (m_validbbox == TRUE);
316 assert (other.GetValid());
317
318 Expand(other);
319 return *this;
320 }
321
322
323 // makes a boundingbox same as the other
324 wxBoundingBox& wxBoundingBox::operator=( const wxBoundingBox &other)
325 {
326 assert (other.GetValid());
327
328 m_minx = other.m_minx;
329 m_maxx = other.m_maxx;
330 m_miny = other.m_miny;
331 m_maxy = other.m_maxy;
332 m_validbbox = other.m_validbbox;
333 return *this;
334 }
335
336 void wxBoundingBox::MapBbox( const wxTransformMatrix& matrix)
337 {
338 assert (m_validbbox == TRUE);
339
340 double x1,y1,x2,y2,x3,y3,x4,y4;
341
342 matrix.TransformPoint( m_minx, m_miny, x1, y1 );
343 matrix.TransformPoint( m_minx, m_maxy, x2, y2 );
344 matrix.TransformPoint( m_maxx, m_maxy, x3, y3 );
345 matrix.TransformPoint( m_maxx, m_miny, x4, y4 );
346
347 double xmin = wxMin(x1,x2);
348 xmin = wxMin(xmin,x3);
349 xmin = wxMin(xmin,x4);
350
351 double xmax = wxMax( x1, x2);
352 xmax = wxMax(xmax,x3);
353 xmax = wxMax(xmax,x4);
354
355 double ymin = wxMin(y1, y2);
356 ymin = wxMin(ymin,y3);
357 ymin = wxMin(ymin,y4);
358
359 double ymax = wxMax(y1,y2);
360 ymax = wxMax(ymax,y3);
361 ymax = wxMax(ymax,y4);
362
363 // Use these min and max values to set the new boundingbox
364 m_minx = xmin;
365 m_miny = ymin;
366 m_maxx = xmax;
367 m_maxy = ymax;
368 }
369