]> git.tdb.fi Git - libs/math.git/blobdiff - source/geometry/hyperbox.h
Beginnings of a geometry library
[libs/math.git] / source / geometry / hyperbox.h
diff --git a/source/geometry/hyperbox.h b/source/geometry/hyperbox.h
new file mode 100644 (file)
index 0000000..2ade28a
--- /dev/null
@@ -0,0 +1,79 @@
+#ifndef MSP_GEOMETRY_HYPERBOX_H_
+#define MSP_GEOMETRY_HYPERBOX_H_
+
+#include <msp/linal/vector.h>
+#include "ray.h"
+#include "shape.h"
+
+namespace Msp {
+namespace Geometry {
+
+template<typename T, unsigned D>
+class HyperBox: public Shape<T, D>
+{
+private:
+       LinAl::Vector<T, D> dimensions;
+
+public:
+       HyperBox();
+       explicit HyperBox(const LinAl::Vector<T, D> &);
+
+       virtual HyperBox *clone() const;
+
+       const LinAl::Vector<T, D> &get_dimensions() const { return dimensions; }
+       T get_dimension(unsigned) const;
+
+       virtual HyperBox<T, D> get_axis_aligned_bounding_box() const { return *this; }
+       virtual bool check_intersection(const Ray<T, D> &) const;
+};
+
+template<typename T, unsigned D>
+inline HyperBox<T, D>::HyperBox()
+{
+       for(unsigned i=0; i<D; ++i)
+               dimensions[i] = 1;
+}
+
+template<typename T, unsigned D>
+inline HyperBox<T, D>::HyperBox(const LinAl::Vector<T, D> &d):
+       dimensions(d)
+{ }
+
+template<typename T, unsigned D>
+inline HyperBox<T, D> *HyperBox<T, D>::clone() const
+{
+       return new HyperBox<T, D>(dimensions);
+}
+
+template<typename T, unsigned D>
+inline T HyperBox<T, D>::get_dimension(unsigned i) const
+{
+       return dimensions[i];
+}
+
+template<typename T, unsigned D>
+inline bool HyperBox<T, D>::check_intersection(const Ray<T, D> &ray) const
+{
+       LinAl::Vector<T, D> half_dim = dimensions/T(2);
+       for(unsigned i=0; i<D; ++i)
+               for(int j=-1; j<=1; j+=2)
+               {
+                       T x = (T(j)*half_dim[i]-ray.get_start()[i])/ray.get_direction()[i];
+                       if(x>0)
+                       {
+                               LinAl::Vector<T, D> p = ray.get_start()+ray.get_direction()*x;
+                               bool inside = true;
+                               for(unsigned k=0; (inside && k<D); ++k)
+                                       inside = (k==i || (p[k]>=-half_dim[k] && p[k]<half_dim[k]));
+                               if(inside)
+                                       return true;
+                       }
+               }
+
+       return false;
+}
+
+} // namespace Geometry
+} // namespace Msp
+
+#endif