1 /**************************************************************************\
2  * Copyright (c) Kongsberg Oil & Gas Technologies AS
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * Redistributions of source code must retain the above copyright notice,
10  * this list of conditions and the following disclaimer.
11  *
12  * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  *
16  * Neither the name of the copyright holder nor the names of its
17  * contributors may be used to endorse or promote products derived from
18  * this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 \**************************************************************************/
32 
33 /*!
34   \class SbBox2i32 SbBox2i32.h Inventor/SbBox2i32.h
35   \brief The SbBox2i32 class is a 2 dimensional box with 32-bit
36   integer coordinates.
37 
38   \ingroup base
39 
40   This box class is used by other classes in Coin for data
41   exchange. It provides storage for two box corners with 32-bit integer
42   coordinates, which is among other things useful for representing
43   screen or canvas areas in absolute window coordinates.
44 
45   \sa SbBox2f, SbBox2d, SbBox3s, SbBox3f, SbBox3d, SbXfBox3f.
46 */
47 
48 // *************************************************************************
49 
50 #include <Inventor/SbBox2i32.h>
51 
52 #include <limits>
53 #include <cassert>
54 
55 #include <Inventor/SbBox2s.h>
56 #include <Inventor/SbBox2f.h>
57 #include <Inventor/SbBox2d.h>
58 #include <Inventor/errors/SoDebugError.h>
59 
60 // *************************************************************************
61 
62 /*!
63   \fn SbBox2i32::SbBox2i32(void)
64 
65   The default constructor makes an empty box.
66 */
67 
68 /*!
69   \fn SbBox2i32::SbBox2i32(int32_t xmin, int32_t ymin, int32_t xmax, int32_t ymax)
70 
71   Constructs a box with the given corner coordinates.
72 
73   \a xmin should be less than \a xmax and \a ymin should be less than
74   \a ymax if you want to make a valid box.
75 */
76 
77 /*!
78   \fn SbBox2i32::SbBox2i32(const SbVec2i32 & minpt, const SbVec2i32 & maxpt)
79 
80   Constructs a box with the given corners.
81 
82   The coordinates of \a min should be less than the coordinates of
83   \a max if you want to make a valid box.
84 */
85 
86 /*!
87   \fn SbBox2i32 &  SbBox2i32::setBounds(int32_t xmin, int32_t ymin, int32_t xmax, int32_t ymax)
88 
89   Reset the boundaries of the box.
90 
91   \a xmin should be less than \a xmax and \a ymin should be less than
92   \a ymax if you want to make a valid box.
93 
94   Returns reference to self.
95 
96   \sa getBounds().
97 */
98 
99 /*!
100   \fn SbBox2i32 & SbBox2i32::setBounds(const SbVec2i32 & boxmin, const SbVec2i32 & boxmax)
101 
102   Reset the boundaries of the box with the given corners.
103 
104   The coordinates of \a min should be less than the coordinates of
105   \a max if you want to make a valid box.
106 
107   Returns reference to self.
108 
109   \sa getBounds().
110 */
111 
112 /*!
113   Reset the boundaries to the boundaries of the given \a box.
114 
115   Returns reference to self.
116 
117   \sa getBounds()
118 */
119 
120 SbBox2i32 &
setBounds(const SbBox2s & box)121 SbBox2i32::setBounds(const SbBox2s & box)
122 {
123   if (box.isEmpty()) {
124     makeEmpty();
125   } else {
126     minpt.setValue(box.getMin());
127     maxpt.setValue(box.getMax());
128   }
129   return *this;
130 }
131 
132 /*!
133   Reset the boundaries to the boundaries of the given \a box.
134 
135   Returns reference to self.
136 
137   \sa getBounds()
138 */
139 
140 SbBox2i32 &
setBounds(const SbBox2f & box)141 SbBox2i32::setBounds(const SbBox2f & box)
142 {
143   if (box.isEmpty()) {
144     makeEmpty();
145   } else {
146     minpt.setValue(box.getMin());
147     maxpt.setValue(box.getMax());
148   }
149   return *this;
150 }
151 
152 /*!
153   Reset the boundaries to the boundaries of the given \a box.
154 
155   Returns reference to self.
156 
157   \sa getBounds()
158 */
159 
160 SbBox2i32 &
setBounds(const SbBox2d & box)161 SbBox2i32::setBounds(const SbBox2d & box)
162 {
163   if (box.isEmpty()) {
164     makeEmpty();
165   } else {
166     minpt.setValue(box.getMin());
167     maxpt.setValue(box.getMax());
168   }
169   return *this;
170 }
171 
172 /*!
173   Marks this as an empty box.
174 
175   \sa isEmpty().
176 */
177 void
makeEmpty(void)178 SbBox2i32::makeEmpty(void)
179 {
180   minpt.setValue(std::numeric_limits<int32_t>::max(), std::numeric_limits<int32_t>::max());
181   maxpt.setValue(-std::numeric_limits<int32_t>::max(), -std::numeric_limits<int32_t>::max());
182 }
183 
184 /*!
185   \fn const SbVec2i32 & SbBox2i32::getMin(void) const
186 
187   Returns the minimum point. This should usually be the lower left corner
188   point of the box.
189 
190   \sa getOrigin(), getMax().
191 */
192 
193 /*!
194   \fn const SbVec2i32 & SbBox2i32::getMax(void) const
195 
196   Returns the maximum point. This should usually be the upper right corner
197   point of the box.
198 
199   \sa getMin().
200 */
201 
202 /*!
203   Extend the boundaries of the box by the given point, i.e. make the
204   point fit inside the box if it isn't already within it.
205 */
206 void
extendBy(const SbVec2i32 & point)207 SbBox2i32::extendBy(const SbVec2i32 & point)
208 {
209   this->minpt.setValue(SbMin(point[0], this->minpt[0]),
210                        SbMin(point[1], this->minpt[1]));
211   this->maxpt.setValue(SbMax(point[0], this->maxpt[0]),
212                        SbMax(point[1], this->maxpt[1]));
213 }
214 
215 /*!
216   Extend the boundaries of the box by the given \a box parameter. This
217   is equal to calling extendBy() twice with the corner points.
218 */
219 void
extendBy(const SbBox2i32 & box)220 SbBox2i32::extendBy(const SbBox2i32 & box)
221 {
222   if (box.isEmpty()) { return; }
223 
224   this->extendBy(box.getMin());
225   this->extendBy(box.getMax());
226 }
227 
228 /*!
229   Check if the given point lies within the boundaries of this box.
230 */
231 SbBool
intersect(const SbVec2i32 & point) const232 SbBox2i32::intersect(const SbVec2i32 & point) const
233 {
234   if((point[0] >= this->minpt[0]) && (point[0] <= this->maxpt[0]) &&
235      (point[1] >= this->minpt[1]) && (point[1] <= this->maxpt[1])) return TRUE;
236   return FALSE;
237 }
238 
239 /*!
240   Check if \a box lies wholly or partly within the boundaries
241   of this box.
242 */
243 SbBool
intersect(const SbBox2i32 & box) const244 SbBox2i32::intersect(const SbBox2i32 & box) const
245 {
246   if((box.getMax()[0] < this->getMin()[0]) ||
247      (box.getMax()[1] < this->getMin()[1]) ||
248      (box.getMin()[0] > this->getMax()[0]) ||
249      (box.getMin()[1] > this->getMax()[1])) return FALSE;
250   return TRUE;
251 }
252 
253 /*!
254   \fn void SbBox2i32::getBounds(int32_t & xmin, int32_t & ymin, int32_t & xmax, int32_t & ymax) const
255 
256   Returns the box boundary coordinates.
257 
258   \sa setBounds(), getMin(), getMax().
259 */
260 
261 /*!
262   \fn void SbBox2i32::getBounds(SbVec2i32 & boxmin, SbVec2i32 & boxmax) const
263 
264   Returns the box corner points.
265 
266   \sa setBounds(), getMin(), getMax().
267 */
268 
269 /*!
270   \fn void SbBox2i32::getOrigin(int32_t & originX, int32_t & originY) const
271 
272   Returns the coordinates of the box origin (i.e. the lower left corner).
273 
274   \sa getMin().
275 */
276 
277 /*!
278   \fn void SbBox2i32::getSize(int32_t & sizeX, int32_t & sizeY) const
279 
280   Returns width and height of box.
281 */
282 
283 /*!
284   \fn float SbBox2i32::getAspectRatio(void) const
285 
286   Returns aspect ratio of box, which is defined as box width divided on
287   box height.
288 */
289 
290 /*!
291   \fn SbBool SbBox2i32::hasArea(void) const
292 */
293 
294 /*!
295   \fn int operator == (const SbBox2i32 & b1, const SbBox2i32 & b2)
296   \relates SbBox2i32
297 
298   Check \a b1 and \a b2 for equality.
299 */
300 
301 /*!
302   \fn int operator != (const SbBox2i32 & b1, const SbBox2i32 & b2)
303   \relates SbBox2i32
304 
305   Check \a b1 and \a b2 for inequality.
306 */
307 
308 #ifdef COIN_TEST_SUITE
BOOST_AUTO_TEST_CASE(checkSize)309 BOOST_AUTO_TEST_CASE(checkSize) {
310   SbVec2i32 min(1,2);
311   SbVec2i32 max(3,4);
312 
313   SbVec2i32 diff = max - min;
314 
315 
316   SbBox2i32 box(min, max);
317 
318   BOOST_CHECK_MESSAGE(box.getSize() == diff,
319                       "Box has incorrect size");
320 
321 }
322 #endif //COIN_TEST_SUITE
323