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 SbBox2s SbBox2s.h Inventor/SbBox2s.h
35 \brief The SbBox2s class is a 2 dimensional box with short
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 short 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/SbBox2s.h>
51
52 #include <limits>
53 #include <cassert>
54
55 #include <Inventor/SbBox2i32.h>
56 #include <Inventor/SbBox2f.h>
57 #include <Inventor/SbBox2d.h>
58 #include <Inventor/errors/SoDebugError.h>
59
60 // *************************************************************************
61
62 /*!
63 \fn SbBox2s::SbBox2s(void)
64
65 The default constructor makes an empty box.
66 */
67
68 /*!
69 \fn SbBox2s::SbBox2s(short xmin, short ymin, short xmax, short 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 SbBox2s::SbBox2s(const SbVec2s & boxmin, const SbVec2s & boxmax)
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 SbBox2s & SbBox2s::setBounds(short xmin, short ymin, short xmax, short 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 SbBox2s & SbBox2s::setBounds(const SbVec2s & boxmin, const SbVec2s & 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 with the boundaries of the given \a box.
114
115 Returns reference to self.
116
117 \sa setBounds()
118 */
119
120 SbBox2s &
setBounds(const SbBox2i32 & box)121 SbBox2s::setBounds(const SbBox2i32 & 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 with the boundaries of the given \a box.
134
135 Returns reference to self.
136
137 \sa setBounds()
138 */
139
140 SbBox2s &
setBounds(const SbBox2f & box)141 SbBox2s::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 with the boundaries of the given \a box.
154
155 Returns reference to self.
156
157 \sa setBounds()
158 */
159
160 SbBox2s &
setBounds(const SbBox2d & box)161 SbBox2s::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 SbBox2s::makeEmpty(void)
179 {
180 minpt.setValue(std::numeric_limits<short>::max(), std::numeric_limits<short>::max());
181 maxpt.setValue(-std::numeric_limits<short>::max(), -std::numeric_limits<short>::max());
182 }
183
184 /*!
185 \fn const SbVec2s & SbBox2s::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 SbVec2s & SbBox2s::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 SbVec2s & point)207 SbBox2s::extendBy(const SbVec2s & point)
208 {
209 // The explicit casts are done to humour the HPUX aCC compiler,
210 // which will otherwise say ``Template deduction failed to find a
211 // match for the call to 'SbMin'''. mortene.
212 this->minpt.setValue(SbMin(static_cast<short>(point[0]), static_cast<short>(this->minpt[0])),
213 SbMin(static_cast<short>(point[1]), static_cast<short>(this->minpt[1])));
214 this->maxpt.setValue(SbMax(static_cast<short>(point[0]), static_cast<short>(this->maxpt[0])),
215 SbMax(static_cast<short>(point[1]), static_cast<short>(this->maxpt[1])));
216 }
217
218 /*!
219 Extend the boundaries of the box by the given \a box parameter. This
220 is equal to calling extendBy() twice with the corner points.
221 */
222 void
extendBy(const SbBox2s & box)223 SbBox2s::extendBy(const SbBox2s & box)
224 {
225 if (box.isEmpty()) { return; }
226
227 this->extendBy(box.getMin());
228 this->extendBy(box.getMax());
229 }
230
231 /*!
232 Check if the given point lies within the boundaries of this box.
233 */
234 SbBool
intersect(const SbVec2s & point) const235 SbBox2s::intersect(const SbVec2s & point) const
236 {
237 if((point[0] >= this->minpt[0]) && (point[0] <= this->maxpt[0]) &&
238 (point[1] >= this->minpt[1]) && (point[1] <= this->maxpt[1])) return TRUE;
239 return FALSE;
240 }
241
242 /*!
243 Check if \a box lies wholly or partly within the boundaries
244 of this box.
245 */
246 SbBool
intersect(const SbBox2s & box) const247 SbBox2s::intersect(const SbBox2s & box) const
248 {
249 if((box.getMax()[0] < this->getMin()[0]) ||
250 (box.getMax()[1] < this->getMin()[1]) ||
251 (box.getMin()[0] > this->getMax()[0]) ||
252 (box.getMin()[1] > this->getMax()[1])) return FALSE;
253 return TRUE;
254 }
255
256 /*!
257 \fn void SbBox2s::getBounds(short & xmin, short & ymin, short & xmax, short & ymax) const
258
259 Returns the box boundary coordinates.
260
261 \sa setBounds(), getMin(), getMax().
262 */
263
264 /*!
265 \fn void SbBox2s::getBounds(SbVec2s & boxmin, SbVec2s & boxmax) const
266
267 Returns the box corner points.
268
269 \sa setBounds(), getMin(), getMax().
270 */
271
272 /*!
273 \fn void SbBox2s::getOrigin(short & originX, short & originY) const
274
275 Returns the coordinates of the box origin (i.e. the lower left corner).
276
277 \sa getMin().
278 */
279
280 /*!
281 \fn void SbBox2s::getSize(short & sizeX, short & sizeY) const
282
283 Returns width and height of box.
284 */
285
286 /*!
287 \fn float SbBox2s::getAspectRatio(void) const
288
289 Returns aspect ratio of box, which is defined as box width divided on
290 box height.
291 */
292
293 /*!
294 \fn int operator == (const SbBox2s & b1, const SbBox2s & b2)
295 \relates SbBox2s
296
297 Check \a b1 and \a b2 for equality.
298 */
299
300 /*!
301 \fn int operator != (const SbBox2s & b1, const SbBox2s & b2)
302 \relates SbBox2s
303
304 Check \a b1 and \a b2 for inequality.
305 */
306
307 /*!
308 \fn SbBool SbBox2s::hasArea(void) const
309 */
310
311 #ifdef COIN_TEST_SUITE
BOOST_AUTO_TEST_CASE(checkSize)312 BOOST_AUTO_TEST_CASE(checkSize) {
313 SbVec2s min(1,2);
314 SbVec2s max(3,4);
315
316 SbVec2s diff = max - min;
317
318
319 SbBox2s box(min, max);
320
321 BOOST_CHECK_MESSAGE(box.getSize() == diff,
322 "Box has incorrect size");
323
324 }
325 #endif //COIN_TEST_SUITE
326