library of assembled shared sources

http://lass.cocamware.com

aabb_2d.inl

Go to the documentation of this file.
00001 /** @file
00002  *  @author Bram de Greve (bramz@users.sourceforge.net)
00003  *  @author Tom De Muer (tomdemuer@users.sourceforge.net)
00004  *
00005  *  *** BEGIN LICENSE INFORMATION ***
00006  *  
00007  *  The contents of this file are subject to the Common Public Attribution License 
00008  *  Version 1.0 (the "License"); you may not use this file except in compliance with 
00009  *  the License. You may obtain a copy of the License at 
00010  *  http://lass.sourceforge.net/cpal-license. The License is based on the 
00011  *  Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover 
00012  *  use of software over a computer network and provide for limited attribution for 
00013  *  the Original Developer. In addition, Exhibit A has been modified to be consistent 
00014  *  with Exhibit B.
00015  *  
00016  *  Software distributed under the License is distributed on an "AS IS" basis, WITHOUT 
00017  *  WARRANTY OF ANY KIND, either express or implied. See the License for the specific 
00018  *  language governing rights and limitations under the License.
00019  *  
00020  *  The Original Code is LASS - Library of Assembled Shared Sources.
00021  *  
00022  *  The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
00023  *  The Original Developer is the Initial Developer.
00024  *  
00025  *  All portions of the code written by the Initial Developer are:
00026  *  Copyright (C) 2004-2007 the Initial Developer.
00027  *  All Rights Reserved.
00028  *  
00029  *  Contributor(s):
00030  *
00031  *  Alternatively, the contents of this file may be used under the terms of the 
00032  *  GNU General Public License Version 2 or later (the GPL), in which case the 
00033  *  provisions of GPL are applicable instead of those above.  If you wish to allow use
00034  *  of your version of this file only under the terms of the GPL and not to allow 
00035  *  others to use your version of this file under the CPAL, indicate your decision by 
00036  *  deleting the provisions above and replace them with the notice and other 
00037  *  provisions required by the GPL License. If you do not delete the provisions above,
00038  *  a recipient may use your version of this file under either the CPAL or the GPL.
00039  *  
00040  *  *** END LICENSE INFORMATION ***
00041  */
00042 
00043 
00044 
00045 #ifndef LASS_GUARDIAN_OF_INCLUSION_PRIM_AABB_2D_INL
00046 #define LASS_GUARDIAN_OF_INCLUSION_PRIM_AABB_2D_INL
00047 
00048 
00049 
00050 #include "aabb_2d.h"
00051 #include <cstdlib>
00052 
00053 
00054 namespace lass
00055 {
00056 
00057 namespace prim
00058 {
00059 
00060 /** Construct an empty bounding box.
00061  */
00062 template <typename T, class MMP>
00063 Aabb2D<T, MMP>::Aabb2D():
00064     min_(TNumTraits::max, TNumTraits::max),
00065     max_(TNumTraits::min, TNumTraits::min)
00066 {
00067     LASS_ASSERT(isEmpty());
00068 }
00069 
00070 
00071 
00072 /** Construct bounding box, spanned by min and max
00073  */
00074 template <typename T, class MMP>
00075 Aabb2D<T, MMP>::Aabb2D(const TPoint& min, const TPoint& max):
00076     min_(min),
00077     max_(max)
00078 {
00079     MMP::checkMinMax(min_, max_);
00080     LASS_ASSERT(isValid());
00081 }
00082 
00083 
00084 
00085 /** Construct bounding box around a single point (min == max)
00086  */
00087 template <typename T, class MMP>
00088 Aabb2D<T, MMP>::Aabb2D(const TPoint& point):
00089     min_(point),
00090     max_(point)
00091 {
00092     LASS_ASSERT(isValid());
00093 }
00094 
00095 
00096 
00097 /** copy constructor.
00098  */
00099 template <typename T, class MMP>
00100 template <class MMP2>
00101 Aabb2D<T, MMP>::Aabb2D(const Aabb2D<T, MMP2>& other):
00102     min_(other.min()),
00103     max_(other.max())
00104 {
00105     LASS_ASSERT(isValid());
00106 }
00107 
00108 
00109 
00110 /** return corner with smallest component values
00111  */
00112 template <typename T, class MMP>
00113 const typename Aabb2D<T, MMP>::TPoint&
00114 Aabb2D<T, MMP>::min() const
00115 {
00116     LASS_ASSERT(isValid());
00117     return min_;
00118 }
00119 
00120 
00121 
00122 /** Return corner with largest component values
00123  */
00124 template <typename T, class MMP>
00125 const typename Aabb2D<T, MMP>::TPoint&
00126 Aabb2D<T, MMP>::max() const
00127 {
00128     LASS_ASSERT(isValid());
00129     return max_;
00130 }
00131 
00132 
00133 
00134 /** set corner with smallest component values
00135  */
00136 template <typename T, class MMP>
00137 void Aabb2D<T, MMP>::setMin(const TPoint& min)
00138 {
00139     if (isEmpty())
00140     {
00141         min_ = min;
00142         max_ = min;
00143     }
00144     else
00145     {
00146         MMP::setMin(min_, max_, min);
00147     }
00148     LASS_ASSERT(isValid());
00149 }
00150 
00151 
00152 
00153 /** set corner with larges component values
00154  */
00155 template <typename T, class MMP>
00156 void Aabb2D<T, MMP>::setMax(const TPoint& max)
00157 {
00158     if (isEmpty())
00159     {
00160         min_ = max;
00161         max_ = max;
00162     }
00163     else
00164     {
00165         MMP::setMax(min_, max_, max);
00166     }
00167     LASS_ASSERT(isValid());
00168 }
00169 
00170 
00171 
00172 /** assign one bounding box to another.
00173  */
00174 template <typename T, class MMP>
00175 template <class MMP2>
00176 typename Aabb2D<T, MMP>::TSelf&
00177 Aabb2D<T, MMP>::operator=(const Aabb2D<T, MMP2>& other)
00178 {
00179     TSelf temp(other);
00180     swap(temp);
00181     return *this;
00182 }
00183 
00184 
00185 
00186 /** Expand bounding box so it contains point.
00187  */
00188 template <typename T, class MMP>
00189 typename Aabb2D<T, MMP>::TSelf&
00190 Aabb2D<T, MMP>::operator+=(const TPoint& point)
00191 {
00192     min_ = pointwiseMin(min_, point);
00193     max_ = pointwiseMax(max_, point);
00194     LASS_ASSERT(isValid());
00195     return *this;
00196 }
00197 
00198 
00199 
00200 /** Expand bounding box so it contains the other bounding box.
00201  */
00202 template <typename T, class MMP>
00203 template <class MMP2>
00204 typename Aabb2D<T, MMP>::TSelf&
00205 Aabb2D<T, MMP>::operator+=(const Aabb2D<T, MMP2>& other)
00206 {
00207     min_ = pointwiseMin(min_, other.min());
00208     max_ = pointwiseMax(max_, other.max());
00209     LASS_ASSERT(isValid());
00210     return *this;
00211 }
00212 
00213 
00214 /** Expand bounding box by distance iDistance.  Negative values causing
00215  *  reversal of the bounding box will cause the box to shrink to the
00216  *  empty box.
00217  */
00218 template <typename T, class MMP>
00219 void Aabb2D<T, MMP>::grow(TParam iDistance)
00220 {
00221     min_.x -= iDistance;
00222     max_.x += iDistance;
00223     min_.y -= iDistance;
00224     max_.y += iDistance;
00225     if (max_.x < min_.x || max_.y < min_.y)
00226     {
00227         clear();
00228     }
00229     LASS_ASSERT(isValid());
00230 }
00231 
00232 
00233 
00234 /** Scale bounding box by scale iScale.  Fractions will shrink the bounding box.
00235  *  The origin of scaling is the center of the bounding box.  Negative values of the
00236  *  scale have same effect as positive ones.
00237  */
00238 template <typename T, class MMP>
00239 void Aabb2D<T, MMP>::scale(TParam iScale)
00240 {
00241     const TVector extra = size() * ((num::abs(iScale) - 1) / 2);
00242     min_ -= extra;
00243     max_ += extra;
00244     LASS_ASSERT(isValid());
00245 }
00246 
00247 
00248 
00249 /** Return the center point of the bounding box.
00250  *  We return a homogeneous point to avoid the division by two (that might not be supported
00251  *  by some types like integers)
00252  */
00253 template <typename T, class MMP>
00254 const typename Aabb2D<T, MMP>::TPointH
00255 Aabb2D<T, MMP>::center() const
00256 {
00257     LASS_ASSERT(isValid());
00258     return min_ + max_;
00259 }
00260 
00261 
00262 
00263 /** Return size of bounding box per axis, max - min.
00264  */
00265 template <typename T, class MMP>
00266 const typename Aabb2D<T, MMP>::TVector
00267 Aabb2D<T, MMP>::size() const
00268 {
00269     LASS_ASSERT(isValid());
00270     return max_ - min_;
00271 }
00272 
00273 
00274 
00275 /** Returns perimeter of bounding box.
00276  */
00277 template <typename T, class MMP>
00278 const typename Aabb2D<T, MMP>::TValue
00279 Aabb2D<T, MMP>::perimeter() const
00280 {
00281     LASS_ASSERT(isValid());
00282     const TVector result = size();
00283     return 2 * (result.x + result.y);
00284 }
00285 
00286 
00287 
00288 /** Returns area of bounding box.
00289  */
00290 template <typename T, class MMP>
00291 const typename Aabb2D<T, MMP>::TValue
00292 Aabb2D<T, MMP>::area() const
00293 {
00294     LASS_ASSERT(isValid());
00295     const TVector result = size();
00296     return result.x * result.y;
00297 }
00298 
00299 
00300 /** Classify if a point is in or outside the bounding box, or on its surface
00301  *  @return sInside, sSurface, sOutside
00302  */
00303 template <typename T, class MMP>
00304 const Side Aabb2D<T, MMP>::classify(const TPoint& point) const
00305 {
00306     LASS_ASSERT(isValid());
00307 
00308     if (point.x > min_.x && point.x < max_.x &&
00309         point.y > min_.y && point.y < max_.y)
00310     {
00311         return sInside;
00312     }
00313 
00314     if (point.x < min_.x || point.x > max_.x ||
00315         point.y < min_.y || point.y > max_.y)
00316     {
00317         return sOutside;
00318     }
00319 
00320     return sSurface;
00321 }
00322 
00323 
00324 
00325 /** Returns true if point is inside bounding box or on its surface.
00326  *  Is equivalent to this->classify(point) != sOutside, but might be faster.
00327  */
00328 template <typename T, class MMP>
00329 const bool Aabb2D<T, MMP>::contains(const TPoint& point) const
00330 {
00331     LASS_ASSERT(isValid());
00332     return  point.x >= min_.x && point.x <= max_.x &&
00333             point.y >= min_.y && point.y <= max_.y;
00334 }
00335 
00336 
00337 
00338 /** Returns true if the AABB other is inside (or on its surface) this AABB.
00339  *  - Is equivalent to this->contains(other.min()) && this->contains(other.max()).
00340  *  - if other is an empty AABB, it will always return true (an empty set is always a part of
00341  *    any other set).
00342  */
00343 template <typename T, class MMP>
00344 template <class MMP2>
00345 const bool Aabb2D<T, MMP>::contains(const Aabb2D<T, MMP2>& other) const
00346 {
00347     LASS_ASSERT(isValid() && other.isValid());
00348     return other.min().x >= min_.x && other.max().x <= max_.x
00349         && other.min().y >= min_.y && other.max().y <= max_.y;
00350 }
00351 
00352 
00353 
00354 /** Check if two axis-aligned bounding boxes do intersect.
00355  *  @return @arg false      intersection of the AABBs is empty.
00356  *          @arg true       intersection of the AABBs is not empty.
00357  *
00358  *  @par FAQ: What's the difference between @c this->intersects(other) and @c this->collides(other) ?
00359  *      When two AABB are touching each other (surface to surface), the intersection isn't empty.
00360  *      i.e. the intersection is the line of points that belong to both the surfaces of the AABBs.
00361  *      In that case, the intersection is a degenerated AABB though, one with @c area()==0.
00362  *      In collision detection however, you don't want this degenerated case of intersection to be
00363  *      considered as a collision.  Two bodies may touch, but the must not have an overlap thas has a
00364  *      non-zero area.  That's why we have two methods: @c intersects returns true on touching
00365  *      AABBs, @c collides will return false.  Of course, in the non-degenerate cases, they behave the
00366  *      same.
00367  *
00368  *  Use the seperating axis test to test if two AABB's do intersect:
00369  *  GOMEZ M. (1999), <i>Simple Intersection Tests For Games</i>, Gamasutra,
00370  *  http://www.gamasutra.com,
00371  *  http://www.gamasutra.com/features/19991018/Gomez_3.htm
00372  */
00373 template <typename T, class MMP>
00374 template <class MMP2>
00375 const bool Aabb2D<T, MMP>::intersects(const Aabb2D<T, MMP2>& other) const
00376 {
00377     LASS_ASSERT(isValid() && other.isValid());
00378 
00379     // test if both AABB's do intersect by using the SEPERATING AXIS TEST.
00380     // notice that the weight of the homogenous points a.center() and b.center() is two,
00381     // so we can avond the division by two of doubleExtend.
00382     // that's why we also have to just take the sum of the sizes and not the half sum.
00383 
00384     LASS_ASSERT(center().weight() == 2 && other.center().weight() == 2);
00385     const TPointH doubleCenterToCenter = center() - other.center();
00386 
00387     LASS_ASSERT(doubleCenterToCenter.weight() == 0);
00388     const typename TPointH::TVector doubleCenterDistance =
00389         doubleCenterToCenter.position().transform(num::abs);
00390 
00391     const TVector doubleExtend = size() + other.size();
00392     return doubleCenterDistance.x <= doubleExtend.x && doubleCenterDistance.y <= doubleExtend.y;
00393 }
00394 
00395 
00396 
00397 /** Check if two axis-aligned bounding boxes do dollide.
00398  *  @return @arg true       the AABBs do collide.
00399  *          @arg false      they don't.
00400  *
00401  *  @par FAQ: What's the difference between @c this->intersects(other) and @c this->collides(other) ?
00402  *      When two AABB are touching each other (surface to surface), the intersection isn't empty.
00403  *      i.e. the intersection is the line of points that belong to both the surfaces of the AABBs.
00404  *      In that case, the intersection is a degenerated AABB though, one with @c area()==0.
00405  *      In collision detection however, you don't want this degenerated case of intersection to be
00406  *      considered as a collision.  Two bodies may touch, but the must not have an overlap thas has a
00407  *      non-zero area.  That's why we have two methods: @c intersects returns true on touching
00408  *      AABBs, @c collides will return false.  Of course, in the non-degenerate cases, they behave the
00409  *      same.
00410  *
00411  *  Use the seperating axis test to test if two AABB's do intersect:
00412  *  GOMEZ M. (1999), <i>Simple Intersection Tests For Games</i>, Gamasutra,
00413  *  http://www.gamasutra.com,
00414  *  http://www.gamasutra.com/features/19991018/Gomez_3.htm
00415  */
00416 template <typename T, class MMP>
00417 template <class MMP2>
00418 const bool Aabb2D<T, MMP>::collides(const Aabb2D<T, MMP2>& other) const
00419 {
00420     LASS_ASSERT(isValid() && other.isValid());
00421 
00422     // test if both AABB's do intersect by using the SEPERATING AXIS TEST.
00423     // notice that the weight of the homogenous points a.center() and b.center() is two,
00424     // so we can avond the division by two of doubleExtend.
00425     // that's why we also have to just take the sum of the sizes and not the half sum.
00426 
00427     LASS_ASSERT(center().weight() == 2 && other.center().weight() == 2);
00428     const TPointH doubleCenterToCenter = center() - other.center();
00429 
00430     LASS_ASSERT(doubleCenterToCenter.weight() == 0);
00431     const typename TPointH::TVector doubleCenterDistance =
00432         doubleCenterToCenter.position().transform(num::abs);
00433 
00434     const TVector doubleExtend = size() + other.size();
00435     return doubleCenterDistance.x < doubleExtend.x && doubleCenterDistance.y < doubleExtend.y;
00436 }
00437 
00438 
00439 
00440 /** Return a random point so that bounding box contains it.
00441  */
00442 template <typename T, class MMP>
00443 template <class RandomGenerator>
00444 const typename Aabb2D<T, MMP>::TPoint
00445 Aabb2D<T, MMP>::random(RandomGenerator& generator) const
00446 {
00447     LASS_ASSERT(isValid());
00448     num::DistributionUniform<TValue, RandomGenerator> uniform(generator);
00449     const TVector t(uniform(), uniform());
00450     const TPoint result(min_ + t * (max_ - min_));
00451     LASS_ASSERT(contains(result));
00452     return result;
00453 }
00454 
00455 
00456 
00457 /** set AABB to an empty box
00458  */
00459 template <typename T, class MMP>
00460 void Aabb2D<T, MMP>::clear()
00461 {
00462     min_ = TPoint(TNumTraits::max, TNumTraits::max);
00463     max_ = TPoint(TNumTraits::min, TNumTraits::min);
00464     LASS_ASSERT(isValid() && isEmpty());
00465 }
00466 
00467 
00468 
00469 /** Return true if bounding box contains no points.
00470  *  i.e. this->contains(Point3D<T>(x, y, z)) will return false for all possible values of
00471  *  x, y and z.
00472  */
00473 template <typename T, class MMP>
00474 const bool Aabb2D<T, MMP>::isEmpty() const
00475 {
00476     LASS_ASSERT(isValid());
00477     return min_.x > max_.x;
00478 }
00479 
00480 
00481 
00482 /** internal check to see if AABB is valid.
00483  *  There are two valid states for the AABB:
00484  *  @arg <tt>max_.x < min_.x</tt> which means the box is empty
00485  *  @arg <tt>max_.x >= min_.x && max_.y >= min_.y</tt> which means the box is not empty.
00486  *  That gives us an invalid state as well:
00487  *  @arg <tt>max_.x >= min_.x && max_.y < min_.y</tt>.  This state would cause @c isEmpty() to yield
00488  *      false, while there's still nothing in it (there's no single point for which @c contains(p)
00489  *      would return true.
00490  *
00491  *  When the regular minmax policies are used (StrictMinMax and AutoMinMax), there's no way any AABB
00492  *  would become invalid, and this test counts as an invariant to the box.  However, when using the
00493  *  UncheckedMinMax policy, you're on your own.
00494  */
00495 template <typename T, class MMP>
00496 const bool Aabb2D<T, MMP>::isValid() const
00497 {
00498     return (min_.x <= max_.x && min_.y <= max_.y) || (min_.x > max_.x);
00499 }
00500 
00501 
00502 
00503 /** swap two bounding boxes.
00504  */
00505 template <typename T, class MMP>
00506 template <typename MMP2>
00507 void Aabb2D<T, MMP>::swap(Aabb2D<T, MMP2>& other)
00508 {
00509     std::swap(min_, other.min_);
00510     std::swap(max_, other.max_);
00511     LASS_ASSERT(isValid() && other.isValid());
00512 }
00513 
00514 
00515 
00516 // --- free ----------------------------------------------------------------------------------------
00517 
00518 /** join two AABBs
00519  *  @relates Aabb2D
00520  */
00521 template <typename T, class MMPa, class MMPb> inline
00522 const Aabb2D<T, MMPa> operator+(const Aabb2D<T, MMPa>& a, const Aabb2D<T, MMPb>& b)
00523 {
00524     Aabb2D<T, MMPa> result(a);
00525     result += b;
00526     return result;
00527 }
00528 
00529 
00530 
00531 /** add a point to an AABB
00532  *  @relates Aabb2D
00533  */
00534 template <typename T, class MMP> inline
00535 const Aabb2D<T, MMP> operator+(const Aabb2D<T, MMP>& a, const Point2D<T>& b)
00536 {
00537     Aabb2D<T, MMP> result(a);
00538     result += b;
00539     return result;
00540 }
00541 
00542 
00543 
00544 /** add a point to an AABB
00545  *  @relates Aabb2D
00546  */
00547 template <typename T, class MMP> inline
00548 const Aabb2D<T, MMP> operator+(const Point2D<T>& a, const Aabb2D<T, MMP>& b)
00549 {
00550     Aabb2D<T, MMP> result(b);
00551     result += a;
00552     return result;
00553 }
00554 
00555 
00556 
00557 /** create an aabb with a single point in it
00558  *  @relates Aabb2D
00559  */
00560 template <typename T>
00561 const Aabb2D<T> aabb(const Point2D<T>& point)
00562 {
00563     return Aabb2D<T>(point, point);
00564 }
00565 
00566 
00567 
00568 /** distance between AABB and point
00569  *  @relates Aabb2D
00570  *  @param a   AABB
00571  *  @param b   point
00572  *  @return absolute distance between point and AABB.  If point is inside AABB, distance is 0.
00573  *  @pre @a a should not be empty.  Undefined behaviour if it is empty.
00574  */
00575 template <typename T, class MMP> inline
00576 T distance(const Aabb2D<T, MMP>& a, const Point2D<T>& b)
00577 {
00578     LASS_ASSERT(!a.isEmpty());
00579     typedef typename Point2D<T>::TVector TVector;
00580     return pointwiseMax(pointwiseMax(a.min() - b, b - a.max()), TVector()).norm();
00581 }
00582 
00583 
00584 
00585 /** distance between two AABBs
00586  *  @relates Aabb2D
00587  *  @param a   AABB
00588  *  @param b   AABB
00589  *  @return absolute distance.  If one AABB is completely inside the other, distance is 0.
00590  *  @pre @a a and @a b should not be empty.  Undefined behaviour if they are.
00591  */
00592 template <typename T, class MMPa, class MMPb> inline
00593 T distance(const Aabb2D<T, MMPa>& a, const Aabb2D<T, MMPb>& b)
00594 {
00595     LASS_ASSERT(!a.isEmpty() && !b.isEmpty());
00596     typedef typename Point2D<T>::TVector TVector;
00597     return pointwiseMax(pointwiseMax(a.min() - b.max(), b.min() - a.max()), TVector()).norm();
00598 }
00599 
00600 
00601 
00602 /** Calculate the intersection of two axis aligned bounding boxes.
00603  *  @relates lass::prim::Aabb2D
00604  *  @param a the first AABB :)
00605  *  @param b the second AABB
00606  *  @param result the intersection of @a a and @a b.  In contrary to other intersection
00607  *                 functions, this output argument will @e always be assigned, even if there's no
00608  *                 result.  By no result we mean: the intersection is empty.  For most other
00609  *                 intersection functions, we can't assign a meaning full value if there's no
00610  *                 intersection, so we don't.  However, in this case we can assign an @e empty AABB.
00611  *                 And that's exactly what we do.  So, the output argument is @e always valid, even
00612  *                 if the return value suggests otherwise (in fact, you don't have to bother the
00613  *                 return value this time)
00614  *  @return @arg rNone      intersection of the AABBs is empty.
00615  *                          @a result is an @e empty AABB.
00616  *          @arg rOne       intersection of the AABBs is not empty.
00617  *                          @a result contains intersection.
00618  */
00619 template <typename T, class MMPa, class MMPb, class MMPr>
00620 Result intersect(const Aabb2D<T, MMPa>& a, const Aabb2D<T, MMPb>& b, Aabb2D<T, MMPr>& result)
00621 {
00622     LASS_ASSERT(a.isValid() && b.isValid());
00623 
00624     if (!a.intersects(b))
00625     {
00626         result = Aabb2D<T, MMPr>(); // empty box
00627         return rNone;
00628     }
00629 
00630     // by now, we're sure they are intersecting.  now, we only need the highest minimum
00631     // and lowest maximum.
00632     //
00633     result = Aabb2D<T, MMPr>(pointwiseMax(a.min(), b.min()), pointwiseMin(a.max(), b.max()));
00634     return rOne;
00635 }
00636 
00637 
00638 
00639 /** @relates lass::prim::Aabb2D
00640  */
00641 template <typename T, typename MMPa, typename MMPb> inline
00642 const bool intersects(const Aabb2D<T, MMPa>& a, const Aabb2D<T, MMPb>& b)
00643 {
00644     return a.intersects(b);
00645 }
00646 
00647 
00648 
00649 /** @relates lass::prim::Aabb2D
00650  */
00651 template <typename T, typename MMP> inline
00652 const bool intersects(const Aabb2D<T, MMP>& a, const Point2D<T>& b)
00653 {
00654     return a.contains(b);
00655 }
00656 
00657 
00658 
00659 /** @relates lass::prim::Aabb2D
00660  */
00661 template <typename T, typename MMP> inline
00662 const bool intersects(const Point2D<T>& a, const Aabb2D<T, MMP>& b)
00663 {
00664     return b.contains(a);
00665 }
00666 
00667 
00668 
00669 /** @relates lass::prim::Aabb2D
00670  */
00671 template <typename T, typename MMPa, typename MMPb> inline
00672 const bool collides(const Aabb2D<T, MMPa>& a, const Aabb2D<T, MMPb>& b)
00673 {
00674     return a.collides(b);
00675 }
00676 
00677 
00678 
00679 /** @relates lass::prim::Aabb2D
00680  */
00681 template <typename T, typename MMP> inline
00682 const bool collides(const Aabb2D<T, MMP>& a, const Point2D<T>& b)
00683 {
00684     typedef typename Aabb2D<T, MMP>::TPoint TPoint;
00685     const TPoint& min = a.min();
00686     const TPoint& max = a.max();
00687     return min.x < b.x && b.x < max.x && min.y < b.y && b.y < max.y;
00688 }
00689 
00690 
00691 
00692 /** @relates lass::prim::Aabb2D
00693  */
00694 template <typename T, typename MMP> inline
00695 const bool collides(const Point2D<T>& a, const Aabb2D<T, MMP>& b)
00696 {
00697     return collides(b, a);
00698 }
00699 
00700 
00701 
00702 /** @relates lass::prim::Aabb2D
00703  */
00704 template <typename T, class MMP>
00705 std::ostream& operator<<(std::ostream& ioOStream, const Aabb2D<T, MMP>& aabb)
00706 {
00707     LASS_ENFORCE_STREAM(ioOStream) << "{m=" << aabb.min() << ", M=" << aabb.max() << "}";
00708     return ioOStream;
00709 }
00710 
00711 
00712 
00713 /** @relates lass::prim::Aabb2D
00714  */
00715 template<typename T, class MMP>
00716 io::XmlOStream& operator<<(io::XmlOStream& ioOStream, const Aabb2D<T, MMP>& aabb)
00717 {
00718     LASS_ENFORCE_STREAM(ioOStream)
00719         << "<Aabb2D>\n"
00720         << "<min>" << aabb.min() << "</min>\n"
00721         << "<max>" << aabb.max() << "</max>\n"
00722         << "</Aabb2D>\n";
00723 
00724     return ioOStream;
00725 }
00726 
00727 
00728 
00729 /** @relates lass::prim::Aabb2D
00730  */
00731 template <typename T, class MMP>
00732 io::MatlabOStream& operator<<(io::MatlabOStream& ioOStream, const Aabb2D<T, MMP>& aabb)
00733 {
00734     typedef typename Aabb2D<T, MMP>::TPoint TPoint;
00735     const TPoint& min = aabb.min();
00736     const TPoint& max = aabb.max();
00737 
00738     ioOStream << "lasthandle = patch(";
00739     ioOStream << "[" << min.x() << "," << max.x() << "," << max.x() << "," << min.x() << "],";
00740     ioOStream << "[" << min.y() << "," << min.y() << "," << max.y() << "," << max.y() << "],";
00741     ioOStream << ioOStream.color() << ",'EdgeColor'," << ioOStream.color() << ",";
00742 
00743     if (ioOStream.flag("wireframe"))
00744     {
00745         ioOStream << "'FaceColor','none',";
00746     }
00747     else
00748     {
00749         ioOStream << "'FaceColor'," << ioOStream.color() << ",'FaceAlpha',0.25";
00750     }
00751     ioOStream << ");\n";
00752 
00753     return ioOStream;
00754 }
00755 
00756 
00757 
00758 }
00759 
00760 }
00761 
00762 #endif

Generated on Mon Nov 10 14:19:57 2008 for Library of Assembled Shared Sources by doxygen 1.5.7.1
SourceForge.net Logo