Library of Assembled Shared Sources
aabb_2d.inl
Go to the documentation of this file.
1/** @file
2 * @author Bram de Greve (bram@cocamware.com)
3 * @author Tom De Muer (tom@cocamware.com)
4 *
5 * *** BEGIN LICENSE INFORMATION ***
6 *
7 * The contents of this file are subject to the Common Public Attribution License
8 * Version 1.0 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://lass.sourceforge.net/cpal-license. The License is based on the
11 * Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover
12 * use of software over a computer network and provide for limited attribution for
13 * the Original Developer. In addition, Exhibit A has been modified to be consistent
14 * with Exhibit B.
15 *
16 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
17 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
18 * language governing rights and limitations under the License.
19 *
20 * The Original Code is LASS - Library of Assembled Shared Sources.
21 *
22 * The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
23 * The Original Developer is the Initial Developer.
24 *
25 * All portions of the code written by the Initial Developer are:
26 * Copyright (C) 2004-2022 the Initial Developer.
27 * All Rights Reserved.
28 *
29 * Contributor(s):
30 *
31 * Alternatively, the contents of this file may be used under the terms of the
32 * GNU General Public License Version 2 or later (the GPL), in which case the
33 * provisions of GPL are applicable instead of those above. If you wish to allow use
34 * of your version of this file only under the terms of the GPL and not to allow
35 * others to use your version of this file under the CPAL, indicate your decision by
36 * deleting the provisions above and replace them with the notice and other
37 * provisions required by the GPL License. If you do not delete the provisions above,
38 * a recipient may use your version of this file under either the CPAL or the GPL.
39 *
40 * *** END LICENSE INFORMATION ***
41 */
42
43
44
45#ifndef LASS_GUARDIAN_OF_INCLUSION_PRIM_AABB_2D_INL
46#define LASS_GUARDIAN_OF_INCLUSION_PRIM_AABB_2D_INL
47
48
49
50#include "aabb_2d.h"
51#include <cstdlib>
52#include <random>
53
54namespace lass
55{
56
57namespace prim
58{
59
60/** Construct an empty bounding box.
61 */
62template <typename T, class MMP>
64 min_(TNumTraits::max, TNumTraits::max),
65 max_(TNumTraits::min, TNumTraits::min)
66{
67 LASS_ASSERT(isEmpty());
68}
69
70
71
72/** Construct bounding box, spanned by min and max
73 */
74template <typename T, class MMP>
75Aabb2D<T, MMP>::Aabb2D(const TPoint& min, const TPoint& max):
76 min_(min),
77 max_(max)
78{
79 MMP::checkMinMax(min_, max_);
80 LASS_ASSERT(isValid());
81}
82
83
84
85/** Construct bounding box around a single point (min == max)
86 */
87template <typename T, class MMP>
88Aabb2D<T, MMP>::Aabb2D(const TPoint& point):
89 min_(point),
90 max_(point)
91{
92 LASS_ASSERT(isValid());
93}
94
95
96
97/** copy constructor.
98 */
99template <typename T, class MMP>
100template <class MMP2>
102 min_(other.min()),
103 max_(other.max())
104{
105 LASS_ASSERT(isValid());
106}
107
108
109
110/** return corner with smallest component values
111 */
112template <typename T, class MMP>
113const typename Aabb2D<T, MMP>::TPoint&
116 LASS_ASSERT(isValid());
117 return min_;
121
122/** Return corner with largest component values
123 */
124template <typename T, class MMP>
125const typename Aabb2D<T, MMP>::TPoint&
128 LASS_ASSERT(isValid());
129 return max_;
133
134/** set corner with smallest component values
135 */
136template <typename T, class MMP>
137void Aabb2D<T, MMP>::setMin(const TPoint& min)
139 if (isEmpty())
141 min_ = min;
142 max_ = min;
144 else
145 {
146 MMP::setMin(min_, max_, min);
147 }
148 LASS_ASSERT(isValid());
149}
150
151
152
153/** set corner with larges component values
154 */
155template <typename T, class MMP>
156void Aabb2D<T, MMP>::setMax(const TPoint& max)
157{
158 if (isEmpty())
159 {
160 min_ = max;
161 max_ = max;
162 }
163 else
164 {
165 MMP::setMax(min_, max_, max);
166 }
167 LASS_ASSERT(isValid());
168}
169
170
171
172/** assign one bounding box to another.
173 */
174template <typename T, class MMP>
175template <class MMP2>
176typename Aabb2D<T, MMP>::TSelf&
178{
179 TSelf temp(other);
180 swap(temp);
181 return *this;
182}
183
184
185
186/** Expand bounding box so it contains point.
187 */
188template <typename T, class MMP>
189typename Aabb2D<T, MMP>::TSelf&
190Aabb2D<T, MMP>::operator+=(const TPoint& point)
191{
192 min_ = pointwiseMin(min_, point);
193 max_ = pointwiseMax(max_, point);
194 LASS_ASSERT(isValid());
195 return *this;
196}
197
198
199
200/** Expand bounding box so it contains the other bounding box.
201 */
202template <typename T, class MMP>
203template <class MMP2>
204typename Aabb2D<T, MMP>::TSelf&
206{
207 min_ = pointwiseMin(min_, other.min());
208 max_ = pointwiseMax(max_, other.max());
209 LASS_ASSERT(isValid());
210 return *this;
211}
212
213
214/** Expand bounding box by distance iDistance. Negative values causing
215 * reversal of the bounding box will cause the box to shrink to the
216 * empty box.
217 */
218template <typename T, class MMP>
219void Aabb2D<T, MMP>::grow(TParam iDistance)
220{
221 min_.x -= iDistance;
222 max_.x += iDistance;
223 min_.y -= iDistance;
224 max_.y += iDistance;
225 if (max_.x < min_.x || max_.y < min_.y)
226 {
227 clear();
228 }
229 LASS_ASSERT(isValid());
230}
231
232
233
234/** Scale bounding box by scale iScale. Fractions will shrink the bounding box.
235 * The origin of scaling is the center of the bounding box. Negative values of the
236 * scale have same effect as positive ones.
237 */
238template <typename T, class MMP>
239void Aabb2D<T, MMP>::scale(TParam iScale)
240{
241 const TVector extra = size() * ((num::abs(iScale) - 1) / 2);
242 min_ -= extra;
243 max_ += extra;
244 LASS_ASSERT(isValid());
245}
246
247
248
249/** Return the center point of the bounding box.
250 * We return a homogeneous point to avoid the division by two (that might not be supported
251 * by some types like integers)
252 */
253template <typename T, class MMP>
254const typename Aabb2D<T, MMP>::TPointH
256{
257 LASS_ASSERT(isValid());
258 return min_ + max_;
259}
260
261
262
263/** Return size of bounding box per axis, max - min.
264 */
265template <typename T, class MMP>
266const typename Aabb2D<T, MMP>::TVector
268{
269 if (isEmpty())
270 {
271 return TVector();
272 }
273 return max_ - min_;
274}
275
276
277
278/** Returns perimeter of bounding box.
279 */
280template <typename T, class MMP>
281const typename Aabb2D<T, MMP>::TValue
283{
284 if (isEmpty())
285 {
286 return 0;
287 }
288 const TVector result = size();
289 return 2 * (result.x + result.y);
290}
291
292
293
294/** Returns area of bounding box.
295 */
296template <typename T, class MMP>
297const typename Aabb2D<T, MMP>::TValue
299{
300 if (isEmpty())
301 {
302 return 0;
303 }
304 const TVector result = size();
305 return result.x * result.y;
306}
307
308
309/** Classify if a point is in or outside the bounding box, or on its surface
310 * @return sInside, sSurface, sOutside
311 */
312template <typename T, class MMP>
313Side Aabb2D<T, MMP>::classify(const TPoint& point) const
314{
315 LASS_ASSERT(isValid());
316
317 if (point.x > min_.x && point.x < max_.x &&
318 point.y > min_.y && point.y < max_.y)
319 {
320 return sInside;
321 }
322
323 if (point.x < min_.x || point.x > max_.x ||
324 point.y < min_.y || point.y > max_.y)
325 {
326 return sOutside;
327 }
328
329 return sSurface;
330}
331
332
333
334/** Returns true if point is inside bounding box or on its surface.
335 * Is equivalent to this->classify(point) != sOutside, but might be faster.
336 */
337template <typename T, class MMP>
338bool Aabb2D<T, MMP>::contains(const TPoint& point) const
339{
340 LASS_ASSERT(isValid());
341 return point.x >= min_.x && point.x <= max_.x &&
342 point.y >= min_.y && point.y <= max_.y;
343}
344
345
346
347/** Returns true if the AABB other is inside (or on its surface) this AABB.
348 * - Is equivalent to this->contains(other.min()) && this->contains(other.max()).
349 * - if other is an empty AABB, it will always return true (an empty set is always a part of
350 * any other set).
351 */
352template <typename T, class MMP>
353template <class MMP2>
355{
356 LASS_ASSERT(isValid() && other.isValid());
357 return other.min().x >= min_.x && other.max().x <= max_.x
358 && other.min().y >= min_.y && other.max().y <= max_.y;
359}
360
361
362
363/** Check if two axis-aligned bounding boxes do intersect.
364 * @return @arg false intersection of the AABBs is empty.
365 * @arg true intersection of the AABBs is not empty.
366 *
367 * @par FAQ: What's the difference between @c this->intersects(other) and @c this->collides(other) ?
368 * When two AABB are touching each other (surface to surface), the intersection isn't empty.
369 * i.e. the intersection is the line of points that belong to both the surfaces of the AABBs.
370 * In that case, the intersection is a degenerated AABB though, one with @c area()==0.
371 * In collision detection however, you don't want this degenerated case of intersection to be
372 * considered as a collision. Two bodies may touch, but the must not have an overlap thas has a
373 * non-zero area. That's why we have two methods: @c intersects returns true on touching
374 * AABBs, @c collides will return false. Of course, in the non-degenerate cases, they behave the
375 * same.
376 *
377 * Use the seperating axis test to test if two AABB's do intersect:
378 * GOMEZ M. (1999), <i>Simple Intersection Tests For Games</i>, Gamasutra,
379 * http://www.gamasutra.com,
380 * http://www.gamasutra.com/features/19991018/Gomez_3.htm
381 */
382template <typename T, class MMP>
383template <class MMP2>
385{
386 LASS_ASSERT(isValid() && other.isValid());
387 if (other.max().x < min_.x || other.min().x > max_.x) return false;
388 if (other.max().y < min_.y || other.min().y > max_.y) return false;
389 return true;
390}
391
392
393
394/** Check if two axis-aligned bounding boxes do dollide.
395 * @return @arg true the AABBs do collide.
396 * @arg false they don't.
397 *
398 * @par FAQ: What's the difference between @c this->intersects(other) and @c this->collides(other) ?
399 * When two AABB are touching each other (surface to surface), the intersection isn't empty.
400 * i.e. the intersection is the line of points that belong to both the surfaces of the AABBs.
401 * In that case, the intersection is a degenerated AABB though, one with @c area()==0.
402 * In collision detection however, you don't want this degenerated case of intersection to be
403 * considered as a collision. Two bodies may touch, but the must not have an overlap thas has a
404 * non-zero area. That's why we have two methods: @c intersects returns true on touching
405 * AABBs, @c collides will return false. Of course, in the non-degenerate cases, they behave the
406 * same.
407 *
408 * Use the seperating axis test to test if two AABB's do intersect:
409 * GOMEZ M. (1999), <i>Simple Intersection Tests For Games</i>, Gamasutra,
410 * http://www.gamasutra.com,
411 * http://www.gamasutra.com/features/19991018/Gomez_3.htm
412 */
413template <typename T, class MMP>
414template <class MMP2>
416{
417 LASS_ASSERT(isValid() && other.isValid());
418 if (other.max().x <= min_.x || other.min().x >= max_.x) return false;
419 if (other.max().y <= min_.y || other.min().y >= max_.y) return false;
420 return true;
421}
422
423
424
425/** Return a random point so that bounding box contains it.
426 */
427template <typename T, class MMP>
428template <class RandomGenerator>
429const typename Aabb2D<T, MMP>::TPoint
430Aabb2D<T, MMP>::random(RandomGenerator& generator) const
431{
432 LASS_ASSERT(isValid());
433 std::uniform_real_distribution<T> uniform;
434 const TVector t(uniform(generator), uniform(generator));
435 const TPoint result(min_ + t * (max_ - min_));
436 LASS_ASSERT(contains(result));
437 return result;
438}
439
440
441
442/** set AABB to an empty box
443 */
444template <typename T, class MMP>
446{
447 min_ = TPoint(TNumTraits::max, TNumTraits::max);
448 max_ = TPoint(TNumTraits::min, TNumTraits::min);
449 LASS_ASSERT(isValid() && isEmpty());
450}
451
452
453
454/** Return true if bounding box contains no points.
455 * i.e. this->contains(Point3D<T>(x, y, z)) will return false for all possible values of
456 * x, y and z.
457 */
458template <typename T, class MMP>
460{
461 LASS_ASSERT(isValid());
462 return min_.x > max_.x;
463}
464
465
466
467/** internal check to see if AABB is valid.
468 * There are two valid states for the AABB:
469 * @arg <tt>max_.x < min_.x</tt> which means the box is empty
470 * @arg <tt>max_.x >= min_.x && max_.y >= min_.y</tt> which means the box is not empty.
471 * That gives us an invalid state as well:
472 * @arg <tt>max_.x >= min_.x && max_.y < min_.y</tt>. This state would cause @c isEmpty() to yield
473 * false, while there's still nothing in it (there's no single point for which @c contains(p)
474 * would return true.
475 *
476 * When the regular minmax policies are used (StrictMinMax and AutoMinMax), there's no way any AABB
477 * would become invalid, and this test counts as an invariant to the box. However, when using the
478 * UncheckedMinMax policy, you're on your own.
479 */
480template <typename T, class MMP>
482{
483 return (min_.x <= max_.x && min_.y <= max_.y) || (min_.x > max_.x);
484}
485
486
487
488/** swap two bounding boxes.
489 */
490template <typename T, class MMP>
491template <typename MMP2>
493{
494 std::swap(min_, other.min_);
495 std::swap(max_, other.max_);
496 LASS_ASSERT(isValid() && other.isValid());
497}
498
499
500
501// --- free ----------------------------------------------------------------------------------------
502
503/** join two AABBs
504 * @relates Aabb2D
505 */
506template <typename T, class MMPa, class MMPb> inline
508{
509 Aabb2D<T, MMPa> result(a);
510 result += b;
511 return result;
512}
513
514
515
516/** add a point to an AABB
517 * @relates Aabb2D
518 */
519template <typename T, class MMP> inline
520const Aabb2D<T, MMP> operator+(const Aabb2D<T, MMP>& a, const Point2D<T>& b)
521{
522 Aabb2D<T, MMP> result(a);
523 result += b;
524 return result;
525}
526
527
528
529/** add a point to an AABB
530 * @relates Aabb2D
531 */
532template <typename T, class MMP> inline
533const Aabb2D<T, MMP> operator+(const Point2D<T>& a, const Aabb2D<T, MMP>& b)
534{
535 Aabb2D<T, MMP> result(b);
536 result += a;
537 return result;
538}
539
540
541
542/** create an aabb with a single point in it
543 * @relates Aabb2D
544 */
545template <typename T>
546const Aabb2D<T> aabb(const Point2D<T>& point)
547{
548 return Aabb2D<T>(point, point);
549}
550
551
552
553/** distance between AABB and point
554 * @relates Aabb2D
555 * @param a AABB
556 * @param b point
557 * @return absolute distance between point and AABB. If point is inside AABB, distance is 0.
558 * @pre @a a should not be empty. Undefined behaviour if it is empty.
559 */
560template <typename T, class MMP> inline
561T distance(const Aabb2D<T, MMP>& a, const Point2D<T>& b)
562{
563 LASS_ASSERT(!a.isEmpty());
564 typedef typename Point2D<T>::TVector TVector;
565 return pointwiseMax(pointwiseMax(a.min() - b, b - a.max()), TVector()).norm();
566}
567
568
569
570/** distance between two AABBs
571 * @relates Aabb2D
572 * @param a AABB
573 * @param b AABB
574 * @return absolute distance. If one AABB is completely inside the other, distance is 0.
575 * @pre @a a and @a b should not be empty. Undefined behaviour if they are.
576 */
577template <typename T, class MMPa, class MMPb> inline
579{
580 LASS_ASSERT(!a.isEmpty() && !b.isEmpty());
581 typedef typename Point2D<T>::TVector TVector;
582 return pointwiseMax(pointwiseMax(a.min() - b.max(), b.min() - a.max()), TVector()).norm();
583}
584
585
586
587/** Calculate the intersection of two axis aligned bounding boxes.
588 * @relates lass::prim::Aabb2D
589 * @param a the first AABB :)
590 * @param b the second AABB
591 * @param result the intersection of @a a and @a b. In contrary to other intersection
592 * functions, this output argument will @e always be assigned, even if there's no
593 * result. By no result we mean: the intersection is empty. For most other
594 * intersection functions, we can't assign a meaning full value if there's no
595 * intersection, so we don't. However, in this case we can assign an @e empty AABB.
596 * And that's exactly what we do. So, the output argument is @e always valid, even
597 * if the return value suggests otherwise (in fact, you don't have to bother the
598 * return value this time)
599 * @return @arg rNone intersection of the AABBs is empty.
600 * @a result is an @e empty AABB.
601 * @arg rOne intersection of the AABBs is not empty.
602 * @a result contains intersection.
603 */
604template <typename T, class MMPa, class MMPb, class MMPr>
606{
607 LASS_ASSERT(a.isValid() && b.isValid());
608
609 if (!a.intersects(b))
610 {
611 result = Aabb2D<T, MMPr>(); // empty box
612 return rNone;
613 }
614
615 // by now, we're sure they are intersecting. now, we only need the highest minimum
616 // and lowest maximum.
617 //
618 result = Aabb2D<T, MMPr>(pointwiseMax(a.min(), b.min()), pointwiseMin(a.max(), b.max()));
619 return rOne;
620}
621
622
623
624/** @relates lass::prim::Aabb2D
625 */
626template <typename T, typename MMPa, typename MMPb> inline
627bool intersects(const Aabb2D<T, MMPa>& a, const Aabb2D<T, MMPb>& b)
628{
629 return a.intersects(b);
630}
631
632
633
634/** @relates lass::prim::Aabb2D
635 */
636template <typename T, typename MMP> inline
637bool intersects(const Aabb2D<T, MMP>& a, const Point2D<T>& b)
638{
639 return a.contains(b);
640}
641
642
643
644/** @relates lass::prim::Aabb2D
645 */
646template <typename T, typename MMP> inline
647bool intersects(const Point2D<T>& a, const Aabb2D<T, MMP>& b)
648{
649 return b.contains(a);
650}
651
652
653
654/** @relates lass::prim::Aabb2D
655 */
656template <typename T, typename MMPa, typename MMPb> inline
657bool collides(const Aabb2D<T, MMPa>& a, const Aabb2D<T, MMPb>& b)
658{
659 return a.collides(b);
660}
661
662
663
664/** @relates lass::prim::Aabb2D
665 */
666template <typename T, typename MMP> inline
667bool collides(const Aabb2D<T, MMP>& a, const Point2D<T>& b)
668{
669 typedef typename Aabb2D<T, MMP>::TPoint TPoint;
670 const TPoint& min = a.min();
671 const TPoint& max = a.max();
672 return min.x < b.x && b.x < max.x && min.y < b.y && b.y < max.y;
673}
674
675
676
677/** @relates lass::prim::Aabb2D
678 */
679template <typename T, typename MMP> inline
680bool collides(const Point2D<T>& a, const Aabb2D<T, MMP>& b)
681{
682 return collides(b, a);
683}
684
685
686
687/** @relates lass::prim::Aabb2D
688 */
689template <typename T, class MMP>
690std::ostream& operator<<(std::ostream& ioOStream, const Aabb2D<T, MMP>& aabb)
691{
692 LASS_ENFORCE_STREAM(ioOStream) << "{m=" << aabb.min() << ", M=" << aabb.max() << "}";
693 return ioOStream;
694}
695
696
697
698/** @relates lass::prim::Aabb2D
699 */
700template<typename T, class MMP>
701io::XmlOStream& operator<<(io::XmlOStream& ioOStream, const Aabb2D<T, MMP>& aabb)
702{
703 LASS_ENFORCE_STREAM(ioOStream)
704 << "<Aabb2D>\n"
705 << "<min>" << aabb.min() << "</min>\n"
706 << "<max>" << aabb.max() << "</max>\n"
707 << "</Aabb2D>\n";
708
709 return ioOStream;
710}
711
712
713
714/** @relates lass::prim::Aabb2D
715 */
716template <typename T, class MMP>
717io::MatlabOStream& operator<<(io::MatlabOStream& ioOStream, const Aabb2D<T, MMP>& aabb)
718{
719 typedef typename Aabb2D<T, MMP>::TPoint TPoint;
720 const TPoint& min = aabb.min();
721 const TPoint& max = aabb.max();
722
723 ioOStream << "lasthandle = patch(";
724 ioOStream << "[" << min.x() << "," << max.x() << "," << max.x() << "," << min.x() << "],";
725 ioOStream << "[" << min.y() << "," << min.y() << "," << max.y() << "," << max.y() << "],";
726 ioOStream << ioOStream.color() << ",'EdgeColor'," << ioOStream.color() << ",";
727
728 if (ioOStream.flag("wireframe"))
729 {
730 ioOStream << "'FaceColor','none',";
731 }
732 else
733 {
734 ioOStream << "'FaceColor'," << ioOStream.color() << ",'FaceAlpha',0.25";
735 }
736 ioOStream << ");\n";
737
738 return ioOStream;
739}
740
741
742
743}
744
745}
746
747#endif
your momma's axis aligned bounding box.
Definition aabb_2d.h:89
const TPoint & min() const
return corner with smallest component values
Definition aabb_2d.inl:114
TSelf & operator=(const Aabb2D< T, MMP2 > &other)
assign one bounding box to another.
Definition aabb_2d.inl:177
const Aabb2D< T, MMP > operator+(const Point2D< T > &a, const Aabb2D< T, MMP > &b)
add a point to an AABB
Definition aabb_2d.inl:533
void clear()
set AABB to an empty box
Definition aabb_2d.inl:445
TSelf & operator+=(const TPoint &point)
Expand bounding box so it contains point.
Definition aabb_2d.inl:190
bool isValid() const
internal check to see if AABB is valid.
Definition aabb_2d.inl:481
const TValue perimeter() const
Returns perimeter of bounding box.
Definition aabb_2d.inl:282
void setMin(const TPoint &min)
set corner with smallest component values
Definition aabb_2d.inl:137
const Aabb2D< T > aabb(const Point2D< T > &point)
create an aabb with a single point in it
Definition aabb_2d.inl:546
bool intersects(const Aabb2D< T, MMP2 > &other) const
Check if two axis-aligned bounding boxes do intersect.
Definition aabb_2d.inl:384
Result intersect(const Aabb2D< T, MMPa > &a, const Aabb2D< T, MMPb > &b, Aabb2D< T, MMPr > &result)
Calculate the intersection of two axis aligned bounding boxes.
Definition aabb_2d.inl:605
bool isEmpty() const
Return true if bounding box contains no points.
Definition aabb_2d.inl:459
const Aabb2D< T, MMPa > operator+(const Aabb2D< T, MMPa > &a, const Aabb2D< T, MMPb > &b)
join two AABBs
Definition aabb_2d.inl:507
T distance(const Aabb2D< T, MMP > &a, const Point2D< T > &b)
distance between AABB and point
Definition aabb_2d.inl:561
bool collides(const Aabb2D< T, MMP2 > &other) const
Check if two axis-aligned bounding boxes do dollide.
Definition aabb_2d.inl:415
const TPointH center() const
Return the center point of the bounding box.
Definition aabb_2d.inl:255
const TValue area() const
Returns area of bounding box.
Definition aabb_2d.inl:298
const TVector size() const
Return size of bounding box per axis, max - min.
Definition aabb_2d.inl:267
void grow(TParam iDistance)
Expand bounding box by distance iDistance.
Definition aabb_2d.inl:219
const TPoint random(RandomGenerator &random) const
Return a random point so that bounding box contains it.
Definition aabb_2d.inl:430
void swap(Aabb2D< T, MMP2 > &other)
swap two bounding boxes.
Definition aabb_2d.inl:492
T distance(const Aabb2D< T, MMPa > &a, const Aabb2D< T, MMPb > &b)
distance between two AABBs
Definition aabb_2d.inl:578
Side classify(const TPoint &point) const
Classify if a point is in or outside the bounding box, or on its surface.
Definition aabb_2d.inl:313
const Aabb2D< T, MMP > operator+(const Aabb2D< T, MMP > &a, const Point2D< T > &b)
add a point to an AABB
Definition aabb_2d.inl:520
bool contains(const TPoint &point) const
Returns true if point is inside bounding box or on its surface.
Definition aabb_2d.inl:338
void scale(TParam iScale)
Scale bounding box by scale iScale.
Definition aabb_2d.inl:239
Aabb2D()
Construct an empty bounding box.
Definition aabb_2d.inl:63
const TPoint & max() const
Return corner with largest component values.
Definition aabb_2d.inl:126
void setMax(const TPoint &max)
set corner with larges component values
Definition aabb_2d.inl:156
T abs(const T &x)
if x < 0 return -x, else return x.
Definition basic_ops.h:145
set of geometrical primitives
Definition aabb_2d.h:81
Side
Different sides of a surface.
Definition side.h:79
@ sOutside
outside the surface
Definition side.h:86
@ sSurface
right on the surface
Definition side.h:87
@ sInside
inside the surface
Definition side.h:85
Result
meta information on the result you have from an operation like an intersection ...
Definition result.h:74
@ rNone
operation has no answer, output arguments are meaningless
Definition result.h:76
@ rOne
there's exactly one answer, 1 output argument contains the answer
Definition result.h:77
Library for Assembled Shared Sources.
Definition config.h:53