]> git.tdb.fi Git - libs/math.git/blobdiff - source/geometry/affinetransformation.h
Put ray and bounding box transformations in AffineTransformation
[libs/math.git] / source / geometry / affinetransformation.h
index 0e377baaa51d633186969ace978494d79edfccf1..15bd92675405a36a4b4205326400256ee3187934 100644 (file)
@@ -3,6 +3,8 @@
 
 #include <msp/linal/squarematrix.h>
 #include "angle.h"
+#include "boundingbox.h"
+#include "ray.h"
 
 namespace Msp {
 namespace Geometry {
@@ -70,6 +72,8 @@ public:
 
        LinAl::Vector<T, D> transform(const LinAl::Vector<T, D> &) const;
        LinAl::Vector<T, D> transform_linear(const LinAl::Vector<T, D> &) const;
+       Ray<T, D> transform(const Ray<T, D> &) const;
+       BoundingBox<T, D> transform(const BoundingBox<T, D> &) const;
 };
 
 template<typename T, unsigned D>
@@ -180,6 +184,44 @@ inline LinAl::Vector<T, D> AffineTransformation<T, D>::transform_linear(const Li
        return LinAl::Vector<T, D>(matrix*LinAl::Vector<T, D+1>(v, T(0)));
 }
 
+template<typename T, unsigned D>
+inline Ray<T, D> AffineTransformation<T, D>::transform(const Ray<T, D> &ray) const
+{
+       LinAl::Vector<T, D> dir = transform_linear(ray.get_direction());
+       return Ray<T, D>(transform(ray.get_start()), dir, ray.get_limit()*dir.norm());
+}
+
+template<typename T, unsigned D>
+inline BoundingBox<T, D> AffineTransformation<T, D>::transform(const BoundingBox<T, D> &bbox) const
+{
+       LinAl::Vector<T, D> min_pt;
+       LinAl::Vector<T, D> max_pt;
+       for(unsigned i=0; i<(1<<D); ++i)
+       {
+               LinAl::Vector<T, D> point;
+               for(unsigned j=0; j<D; ++j)
+                       point[j] = ((i>>j)&1 ? bbox.get_maximum_coordinate(j) : bbox.get_minimum_coordinate(j));
+
+               point = transform(point);
+
+               if(i==0)
+               {
+                       min_pt = point;
+                       max_pt = point;
+               }
+               else
+               {
+                       for(unsigned j=0; j<D; ++j)
+                       {
+                               min_pt[j] = std::min(min_pt[j], point[j]);
+                               max_pt[j] = std::max(max_pt[j], point[j]);
+                       }
+               }
+       }
+
+       return BoundingBox<T, D>(min_pt, max_pt);
+}
+
 } // namespace Geometry
 } // namespace Msp