1 #ifndef MSP_GEOMETRY_HYPERBOX_H_
2 #define MSP_GEOMETRY_HYPERBOX_H_
7 #include <msp/linal/vector.h>
8 #include "boundingbox.h"
11 #include "surfacepoint.h"
17 A shape bounded by planar faces at right angles to each other. Two- and three-
18 dimensional cases are Rectangle and Box, respectively.
20 template<typename T, unsigned D>
21 class HyperBox: public Shape<T, D>
24 LinAl::Vector<T, D> dimensions;
28 explicit HyperBox(const LinAl::Vector<T, D> &);
30 virtual HyperBox *clone() const;
32 const LinAl::Vector<T, D> &get_dimensions() const { return dimensions; }
33 T get_dimension(unsigned) const;
35 virtual BoundingBox<T, D> get_axis_aligned_bounding_box() const;
36 virtual bool contains(const LinAl::Vector<T, D> &) const;
37 virtual unsigned get_max_ray_intersections() const { return 2; }
38 virtual unsigned get_intersections(const Ray<T, D> &, SurfacePoint<T, D> *, unsigned) const;
41 template<typename T, unsigned D>
42 inline HyperBox<T, D>::HyperBox()
44 for(unsigned i=0; i<D; ++i)
48 template<typename T, unsigned D>
49 inline HyperBox<T, D>::HyperBox(const LinAl::Vector<T, D> &d):
52 for(unsigned i=0; i<D; ++i)
53 if(dimensions[i]<=T(0))
54 throw std::invalid_argument("HyperBox::HyperBox");
57 template<typename T, unsigned D>
58 inline HyperBox<T, D> *HyperBox<T, D>::clone() const
60 return new HyperBox<T, D>(dimensions);
63 template<typename T, unsigned D>
64 inline T HyperBox<T, D>::get_dimension(unsigned i) const
69 template<typename T, unsigned D>
70 inline BoundingBox<T, D> HyperBox<T, D>::get_axis_aligned_bounding_box() const
72 LinAl::Vector<T, D> half_dim = dimensions/T(2);
73 return BoundingBox<T, D>(-half_dim, half_dim);
76 template<typename T, unsigned D>
77 inline bool HyperBox<T, D>::contains(const LinAl::Vector<T, D> &point) const
81 for(unsigned i=0; i<D; ++i)
82 if(abs(point[i])>dimensions[i]/T(2))
87 template<typename T, unsigned D>
88 inline unsigned HyperBox<T, D>::get_intersections(const Ray<T, D> &ray, SurfacePoint<T, D> *points, unsigned size) const
95 LinAl::Vector<T, D> half_dim = dimensions/T(2);
97 for(unsigned i=0; (n<size && i<D); ++i)
99 if(!ray.get_direction()[i])
102 for(int j=-1; (n<size && j<=1); j+=2)
104 T x = (T(j)*half_dim[i]-ray.get_start()[i])/ray.get_direction()[i];
105 if(!ray.check_limits(x))
108 LinAl::Vector<T, D> p = ray.get_start()+ray.get_direction()*x;
111 for(unsigned k=0; (inside && k<D); ++k)
112 inside = (k==i || abs(p[k])<=half_dim[k]);
118 points[n].position = p;
119 points[n].normal = LinAl::Vector<T, D>();
120 points[n].normal[i] = j;
121 points[n].distance = x;
123 if(n==1 && x<points[0].distance)
124 std::swap(points[0], points[1]);
135 } // namespace Geometry