#include <cmath>
#include <stdexcept>
#include <msp/linal/vector.h>
-#include "boundingbox.h"
-#include "ray.h"
#include "shape.h"
-#include "surfacepoint.h"
namespace Msp {
namespace Geometry {
const LinAl::Vector<T, D> &get_dimensions() const { return dimensions; }
T get_dimension(unsigned) const;
- virtual BoundingBox<T, D> get_axis_aligned_bounding_box() const;
+ virtual BoundingBox<T, D> get_axis_aligned_bounding_box(unsigned = 0) const;
virtual bool contains(const LinAl::Vector<T, D> &) const;
virtual unsigned get_max_ray_intersections() const { return 2; }
virtual unsigned get_intersections(const Ray<T, D> &, SurfacePoint<T, D> *, unsigned) const;
+ virtual Coverage get_coverage(const BoundingBox<T, D> &) const;
};
template<typename T, unsigned D>
}
template<typename T, unsigned D>
-inline BoundingBox<T, D> HyperBox<T, D>::get_axis_aligned_bounding_box() const
+inline BoundingBox<T, D> HyperBox<T, D>::get_axis_aligned_bounding_box(unsigned) const
{
LinAl::Vector<T, D> half_dim = dimensions/T(2);
return BoundingBox<T, D>(-half_dim, half_dim);
{
if(points)
{
- points[n].position = p;
- points[n].normal = LinAl::Vector<T, D>();
- points[n].normal[i] = j;
- points[n].distance = x;
-
- if(n==1 && x<points[0].distance)
- std::swap(points[0], points[1]);
+ bool entry = (T(j)*ray.get_direction()[i]<T(0));
+ unsigned k = 0;
+ if(n>0 && entry!=points[0].entry)
+ {
+ if(entry)
+ points[1] = points[0];
+ else
+ ++k;
+ }
+ if(k<n && entry==points[k].entry)
+ --n;
+
+ points[k].position = p;
+ points[k].normal = LinAl::Vector<T, D>();
+ points[k].normal[i] = j;
+ points[k].distance = x;
+ points[k].entry = (T(j)*ray.get_direction()[i]<T(0));
}
++n;
return n;
}
+template<typename T, unsigned D>
+inline Coverage HyperBox<T, D>::get_coverage(const BoundingBox<T, D> &bbox) const
+{
+ const LinAl::Vector<T, D> &min_pt = bbox.get_minimum_point();
+ const LinAl::Vector<T, D> &max_pt = bbox.get_maximum_point();
+ LinAl::Vector<T, D> half_dim = dimensions/T(2);
+
+ Coverage coverage = FULL_COVERAGE;
+ for(unsigned i=0; i<D; ++i)
+ {
+ if(max_pt[i]<-half_dim[i] || min_pt[i]>half_dim[i])
+ return NO_COVERAGE;
+ if(min_pt[i]<-half_dim[i] || max_pt[i]>half_dim[i])
+ coverage = PARTIAL_COVERAGE;
+ }
+
+ return coverage;
+}
+
} // namespace Geometry
} // namespace Msp