]> git.tdb.fi Git - libs/math.git/blob - source/geometry/transformedshape.h
9a98f3139d85ef56edcd3fcdb1d8ab47116b6fee
[libs/math.git] / source / geometry / transformedshape.h
1 #ifndef MSP_GEOMETRY_TRANSFORMEDSHAPE_H_
2 #define MSP_GEOMETRY_TRANSFORMEDSHAPE_H_
3
4 #include "affinetransformation.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 TransformedShape
13 {
14 private:
15         Shape<T, D> *shape;
16         AffineTransformation<T, D> transformation;
17
18 public:
19         TransformedShape(const Shape<T, D> &, const AffineTransformation<T, D> &);
20         TransformedShape(const TransformedShape &);
21         TransformedShape &operator=(const TransformedShape &);
22         ~TransformedShape();
23
24         virtual TransformedShape *clone() const;
25
26         const Shape<T, D> &get_shape() const { return *shape; }
27         const AffineTransformation<T, D> &get_transformation() const { return transformation; }
28
29         virtual bool check_intersection(const Ray<T, D> &) const;
30 };
31
32 template<typename T, unsigned D>
33 inline TransformedShape<T, D>::TransformedShape(const Shape<T, D> &s, const AffineTransformation<T, D> &t):
34         shape(s.clone()),
35         transformation(t)
36 { }
37
38 template<typename T, unsigned D>
39 inline TransformedShape<T, D>::TransformedShape(const TransformedShape &other):
40         shape(other.shape->clone()),
41         transformation(other.transformation)
42 { }
43
44 template<typename T, unsigned D>
45 inline TransformedShape<T, D> &TransformedShape<T, D>::operator=(const TransformedShape<T, D> &other)
46 {
47         delete shape;
48         shape = other.shape->clone();
49         transformation = other.transformation();
50 }
51
52 template<typename T, unsigned D>
53 inline TransformedShape<T, D>::~TransformedShape()
54 {
55         delete shape;
56 }
57
58 template<typename T, unsigned D>
59 inline TransformedShape<T, D> *TransformedShape<T, D>::clone() const
60 {
61         return new TransformedShape<T, D>(*this);
62 }
63
64 template<typename T, unsigned D>
65 inline bool TransformedShape<T, D>::check_intersection(const Ray<T, D> &ray) const
66 {
67         // TODO cache the inverse transformation for performance
68         LinAl::SquareMatrix<T, D+1> inverse_trans = LinAl::invert(transformation.get_matrix());
69         Ray<T, D> trans_ray(reduce_vector(inverse_trans*augment_vector(ray.get_start(), T(1))),
70                 reduce_vector(inverse_trans*augment_vector(ray.get_direction(), T(0))));
71         return shape->check_intersection(trans_ray);
72 }
73
74 } // namespace Geometry
75 } // namespace Msp
76
77 #endif