45#ifndef LASS_GUARDIAN_OF_INCLUSION_PRIM_AABB_2D_INL
46#define LASS_GUARDIAN_OF_INCLUSION_PRIM_AABB_2D_INL
62template <
typename T,
class MMP>
64 min_(TNumTraits::
max, TNumTraits::
max),
65 max_(TNumTraits::
min, TNumTraits::
min)
74template <
typename T,
class MMP>
79 MMP::checkMinMax(min_, max_);
87template <
typename T,
class MMP>
99template <
typename T,
class MMP>
112template <
typename T,
class MMP>
113const typename Aabb2D<T, MMP>::TPoint&
124template <
typename T,
class MMP>
125const typename Aabb2D<T, MMP>::TPoint&
136template <
typename T,
class MMP>
146 MMP::setMin(min_, max_,
min);
148 LASS_ASSERT(isValid());
155template <
typename T,
class MMP>
165 MMP::setMax(min_, max_,
max);
174template <
typename T,
class MMP>
176typename Aabb2D<T, MMP>::TSelf&
188template <
typename T,
class MMP>
189typename Aabb2D<T, MMP>::TSelf&
192 min_ = pointwiseMin(min_, point);
193 max_ = pointwiseMax(max_, point);
202template <
typename T,
class MMP>
204typename Aabb2D<T, MMP>::TSelf&
207 min_ = pointwiseMin(min_, other.
min());
208 max_ = pointwiseMax(max_, other.
max());
218template <
typename T,
class MMP>
225 if (max_.x < min_.x || max_.y < min_.y)
238template <
typename T,
class MMP>
241 const TVector extra =
size() * ((
num::abs(iScale) - 1) / 2);
253template <
typename T,
class MMP>
254const typename Aabb2D<T, MMP>::TPointH
265template <
typename T,
class MMP>
266const typename Aabb2D<T, MMP>::TVector
280template <
typename T,
class MMP>
281const typename Aabb2D<T, MMP>::TValue
288 const TVector result =
size();
289 return 2 * (result.x + result.y);
296template <
typename T,
class MMP>
297const typename Aabb2D<T, MMP>::TValue
304 const TVector result =
size();
305 return result.x * result.y;
312template <
typename T,
class MMP>
317 if (point.x > min_.x && point.x < max_.x &&
318 point.y > min_.y && point.y < max_.y)
323 if (point.x < min_.x || point.x > max_.x ||
324 point.y < min_.y || point.y > max_.y)
337template <
typename T,
class MMP>
341 return point.x >= min_.x && point.x <= max_.x &&
342 point.y >= min_.y && point.y <= max_.y;
352template <
typename T,
class MMP>
357 return other.
min().x >= min_.x && other.
max().x <= max_.x
358 && other.
min().y >= min_.y && other.
max().y <= max_.y;
382template <
typename T,
class MMP>
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;
413template <
typename T,
class MMP>
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;
427template <
typename T,
class MMP>
428template <
class RandomGenerator>
429const typename Aabb2D<T, MMP>::TPoint
433 std::uniform_real_distribution<T> uniform;
434 const TVector t(uniform(generator), uniform(generator));
435 const TPoint result(min_ + t * (max_ - min_));
444template <
typename T,
class MMP>
447 min_ = TPoint(TNumTraits::max, TNumTraits::max);
448 max_ = TPoint(TNumTraits::min, TNumTraits::min);
458template <
typename T,
class MMP>
462 return min_.x > max_.x;
480template <
typename T,
class MMP>
483 return (min_.x <= max_.x && min_.y <= max_.y) || (min_.x > max_.x);
490template <
typename T,
class MMP>
491template <
typename MMP2>
494 std::swap(min_, other.min_);
495 std::swap(max_, other.max_);
506template <
typename T,
class MMPa,
class MMPb>
inline
519template <
typename T,
class MMP>
inline
532template <
typename T,
class MMP>
inline
560template <
typename T,
class MMP>
inline
564 typedef typename Point2D<T>::TVector TVector;
565 return pointwiseMax(pointwiseMax(a.
min() - b, b - a.
max()), TVector()).norm();
577template <
typename T,
class MMPa,
class MMPb>
inline
581 typedef typename Point2D<T>::TVector TVector;
582 return pointwiseMax(pointwiseMax(a.
min() - b.
max(), b.
min() - a.
max()), TVector()).norm();
604template <
typename T,
class MMPa,
class MMPb,
class MMPr>
626template <
typename T,
typename MMPa,
typename MMPb>
inline
636template <
typename T,
typename MMP>
inline
637bool intersects(
const Aabb2D<T, MMP>& a,
const Point2D<T>& b)
639 return a.contains(b);
646template <
typename T,
typename MMP>
inline
647bool intersects(
const Point2D<T>& a,
const Aabb2D<T, MMP>& b)
649 return b.contains(a);
656template <
typename T,
typename MMPa,
typename MMPb>
inline
659 return a.collides(b);
666template <
typename T,
typename MMP>
inline
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;
679template <
typename T,
typename MMP>
inline
682 return collides(b, a);
689template <
typename T,
class MMP>
690std::ostream& operator<<(std::ostream& ioOStream,
const Aabb2D<T, MMP>& aabb)
692 LASS_ENFORCE_STREAM(ioOStream) <<
"{m=" << aabb.min() <<
", M=" << aabb.max() <<
"}";
700template<
typename T,
class MMP>
701io::XmlOStream& operator<<(io::XmlOStream& ioOStream,
const Aabb2D<T, MMP>& aabb)
703 LASS_ENFORCE_STREAM(ioOStream)
705 <<
"<min>" << aabb.min() <<
"</min>\n"
706 <<
"<max>" << aabb.max() <<
"</max>\n"
716template <
typename T,
class MMP>
717io::MatlabOStream& operator<<(io::MatlabOStream& ioOStream,
const Aabb2D<T, MMP>& aabb)
719 typedef typename Aabb2D<T, MMP>::TPoint TPoint;
720 const TPoint& min = aabb.min();
721 const TPoint& max = aabb.max();
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() <<
",";
728 if (ioOStream.flag(
"wireframe"))
730 ioOStream <<
"'FaceColor','none',";
734 ioOStream <<
"'FaceColor'," << ioOStream.color() <<
",'FaceAlpha',0.25";
your momma's axis aligned bounding box.
const TPoint & min() const
return corner with smallest component values
TSelf & operator=(const Aabb2D< T, MMP2 > &other)
assign one bounding box to another.
const Aabb2D< T, MMP > operator+(const Point2D< T > &a, const Aabb2D< T, MMP > &b)
add a point to an AABB
void clear()
set AABB to an empty box
TSelf & operator+=(const TPoint &point)
Expand bounding box so it contains point.
bool isValid() const
internal check to see if AABB is valid.
const TValue perimeter() const
Returns perimeter of bounding box.
void setMin(const TPoint &min)
set corner with smallest component values
const Aabb2D< T > aabb(const Point2D< T > &point)
create an aabb with a single point in it
bool intersects(const Aabb2D< T, MMP2 > &other) const
Check if two axis-aligned bounding boxes do intersect.
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.
bool isEmpty() const
Return true if bounding box contains no points.
const Aabb2D< T, MMPa > operator+(const Aabb2D< T, MMPa > &a, const Aabb2D< T, MMPb > &b)
join two AABBs
T distance(const Aabb2D< T, MMP > &a, const Point2D< T > &b)
distance between AABB and point
bool collides(const Aabb2D< T, MMP2 > &other) const
Check if two axis-aligned bounding boxes do dollide.
const TPointH center() const
Return the center point of the bounding box.
const TValue area() const
Returns area of bounding box.
const TVector size() const
Return size of bounding box per axis, max - min.
void grow(TParam iDistance)
Expand bounding box by distance iDistance.
const TPoint random(RandomGenerator &random) const
Return a random point so that bounding box contains it.
void swap(Aabb2D< T, MMP2 > &other)
swap two bounding boxes.
T distance(const Aabb2D< T, MMPa > &a, const Aabb2D< T, MMPb > &b)
distance between two AABBs
Side classify(const TPoint &point) const
Classify if a point is in or outside the bounding box, or on its surface.
const Aabb2D< T, MMP > operator+(const Aabb2D< T, MMP > &a, const Point2D< T > &b)
add a point to an AABB
bool contains(const TPoint &point) const
Returns true if point is inside bounding box or on its surface.
void scale(TParam iScale)
Scale bounding box by scale iScale.
Aabb2D()
Construct an empty bounding box.
const TPoint & max() const
Return corner with largest component values.
void setMax(const TPoint &max)
set corner with larges component values
T abs(const T &x)
if x < 0 return -x, else return x.
set of geometrical primitives
Side
Different sides of a surface.
@ sOutside
outside the surface
@ sSurface
right on the surface
@ sInside
inside the surface
Result
meta information on the result you have from an operation like an intersection ...
@ rNone
operation has no answer, output arguments are meaningless
@ rOne
there's exactly one answer, 1 output argument contains the answer
Library for Assembled Shared Sources.