]> git.tdb.fi Git - libs/math.git/blob - source/geometry/negation.h
91802f8bce9906cfdadcae3bc7382c6e193cb423
[libs/math.git] / source / geometry / negation.h
1 #ifndef MSP_GEOMETRY_NEGATION_H_
2 #define MSP_GEOMETRY_NEGATION_H_
3
4 #include "shape.h"
5
6 namespace Msp {
7 namespace Geometry {
8
9 /**
10 Negates a shape.  Not particulary useful on its own, but can be used together
11 with Intersection to cut holes.
12 */
13 template<typename T, unsigned D>
14 class Negation: public Shape<T, D>
15 {
16 private:
17         Shape<T, D> *shape;
18
19 public:
20         Negation(const Shape<T, D> &);
21         Negation(const Negation &);
22         Negation &operator=(const Negation &);
23         ~Negation();
24
25         virtual Negation *clone() const;
26
27         const Shape<T, D> &get_shape() const { return *shape; }
28
29         virtual BoundingBox<T, D> get_axis_aligned_bounding_box(unsigned = 0) const;
30         virtual bool contains(const LinAl::Vector<T, D> &) const;
31         virtual unsigned get_max_ray_intersections() const { return shape->get_max_ray_intersections(); }
32         virtual unsigned get_intersections(const Ray<T, D> &, SurfacePoint<T, D> *, unsigned) const;
33         virtual Coverage get_coverage(const BoundingBox<T, D> &) const;
34 };
35
36 template<typename T, unsigned D>
37 inline Negation<T, D>::Negation(const Shape<T, D> &s):
38         shape(s.clone())
39 { }
40
41 template<typename T, unsigned D>
42 inline Negation<T, D>::Negation(const Negation<T, D> &other):
43         shape(other.shape->clone())
44 { }
45
46 template<typename T, unsigned D>
47 inline Negation<T, D> &Negation<T, D>::operator=(const Negation<T, D> &other)
48 {
49         delete shape;
50         shape = other.shape->clone();
51         return *this;
52 }
53
54 template<typename T, unsigned D>
55 inline Negation<T, D>::~Negation()
56 {
57         delete shape;
58 }
59
60 template<typename T, unsigned D>
61 inline Negation<T, D> *Negation<T, D>::clone() const
62 {
63         return new Negation<T, D>(*shape);
64 }
65
66 template<typename T, unsigned D>
67 inline BoundingBox<T, D> Negation<T, D>::get_axis_aligned_bounding_box(unsigned detail) const
68 {
69         return ~shape->get_axis_aligned_bounding_box(detail);
70 }
71
72 template<typename T, unsigned D>
73 inline bool Negation<T, D>::contains(const LinAl::Vector<T, D> &point) const
74 {
75         return !shape->contains(point);
76 }
77
78 template<typename T, unsigned D>
79 inline unsigned Negation<T, D>::get_intersections(const Ray<T, D> &ray, SurfacePoint<T, D> *points, unsigned size) const
80 {
81         unsigned count = shape->get_intersections(ray, points, size);
82         for(unsigned i=0; i<count; ++i)
83         {
84                 points[i].normal = -points[i].normal;
85                 points[i].entry = !points[i].entry;
86         }
87         return count;
88 }
89
90 template<typename T, unsigned D>
91 inline Coverage Negation<T, D>::get_coverage(const BoundingBox<T, D> &bbox) const
92 {
93         Coverage coverage = shape->get_coverage(bbox);
94         if(coverage==FULL_COVERAGE)
95                 return NO_COVERAGE;
96         else if(coverage==NO_COVERAGE)
97                 return FULL_COVERAGE;
98         else
99                 return PARTIAL_COVERAGE;
100 }
101
102 } // namespace Geometry
103 } // namespace Msp
104
105 #endif