]> git.tdb.fi Git - libs/math.git/blob - source/geometry/hyperbox.h
Beginnings of a geometry library
[libs/math.git] / source / geometry / hyperbox.h
1 #ifndef MSP_GEOMETRY_HYPERBOX_H_
2 #define MSP_GEOMETRY_HYPERBOX_H_
3
4 #include <msp/linal/vector.h>
5 #include "ray.h"
6 #include "shape.h"
7
8 namespace Msp {
9 namespace Geometry {
10
11 template<typename T, unsigned D>
12 class HyperBox: public Shape<T, D>
13 {
14 private:
15         LinAl::Vector<T, D> dimensions;
16
17 public:
18         HyperBox();
19         explicit HyperBox(const LinAl::Vector<T, D> &);
20
21         virtual HyperBox *clone() const;
22
23         const LinAl::Vector<T, D> &get_dimensions() const { return dimensions; }
24         T get_dimension(unsigned) const;
25
26         virtual HyperBox<T, D> get_axis_aligned_bounding_box() const { return *this; }
27         virtual bool check_intersection(const Ray<T, D> &) const;
28 };
29
30 template<typename T, unsigned D>
31 inline HyperBox<T, D>::HyperBox()
32 {
33         for(unsigned i=0; i<D; ++i)
34                 dimensions[i] = 1;
35 }
36
37 template<typename T, unsigned D>
38 inline HyperBox<T, D>::HyperBox(const LinAl::Vector<T, D> &d):
39         dimensions(d)
40 { }
41
42 template<typename T, unsigned D>
43 inline HyperBox<T, D> *HyperBox<T, D>::clone() const
44 {
45         return new HyperBox<T, D>(dimensions);
46 }
47
48 template<typename T, unsigned D>
49 inline T HyperBox<T, D>::get_dimension(unsigned i) const
50 {
51         return dimensions[i];
52 }
53
54 template<typename T, unsigned D>
55 inline bool HyperBox<T, D>::check_intersection(const Ray<T, D> &ray) const
56 {
57         LinAl::Vector<T, D> half_dim = dimensions/T(2);
58         for(unsigned i=0; i<D; ++i)
59                 for(int j=-1; j<=1; j+=2)
60                 {
61                         T x = (T(j)*half_dim[i]-ray.get_start()[i])/ray.get_direction()[i];
62                         if(x>0)
63                         {
64                                 LinAl::Vector<T, D> p = ray.get_start()+ray.get_direction()*x;
65                                 bool inside = true;
66                                 for(unsigned k=0; (inside && k<D); ++k)
67                                         inside = (k==i || (p[k]>=-half_dim[k] && p[k]<half_dim[k]));
68                                 if(inside)
69                                         return true;
70                         }
71                 }
72
73         return false;
74 }
75
76 } // namespace Geometry
77 } // namespace Msp
78
79 #endif