1 | #ifndef SPHERE_HPP |
2 | #define SPHERE_HPP |
3 | |
4 | #include <boost/fusion/sequence/intrinsic/at_c.hpp> |
5 | #include <boost/fusion/include/at_c.hpp> |
6 | #include <boost/fusion/container/vector.hpp> |
7 | #include <boost/fusion/include/vector.hpp> |
8 | #include <boost/fusion/container/vector/vector_fwd.hpp> |
9 | #include <boost/fusion/include/vector_fwd.hpp> |
10 | #include "boost/multi_array.hpp" |
11 | #include "Point.hpp" |
12 | |
13 | |
14 | /*! \brief This class implement the Sphere concept in an N-dimensional space |
15 | * |
16 | * This class implement the sphere shape in an N-dimensional space |
17 | * |
18 | * \tparam T type of the space |
19 | * \tparam dim dimensionality |
20 | * |
21 | */ |
22 | |
23 | template<unsigned int dim ,typename T> class Sphere |
24 | { |
25 | public: |
26 | |
27 | //! boost fusion that store the point |
28 | typedef boost::fusion::vector<T[dim],T> type; |
29 | |
30 | //! Structure that store the data |
31 | type data; |
32 | |
33 | //! property id of the center position of the sphere |
34 | static const unsigned int x = 0; |
35 | //! property id of the radius of the sphere |
36 | static const unsigned int r = 1; |
37 | |
38 | /*! \brief Get the component i of the center |
39 | * |
40 | * \param i coordinate |
41 | * \return the coordinate i of the center |
42 | * |
43 | */ |
44 | __device__ __host__ T center(unsigned int i) |
45 | { |
46 | return boost::fusion::at_c<x>(data)[i]; |
47 | } |
48 | |
49 | /*! \brief Sphere constructor |
50 | * |
51 | * Sphere constructor |
52 | * |
53 | * \tparam k dimensionality of the center point (and the sphere) |
54 | * \param c center point |
55 | * \param radius |
56 | * |
57 | */ |
58 | __device__ __host__ Sphere(const Sphere<dim,T> & sph) |
59 | { |
60 | // Copy the center |
61 | for (int i = 0 ; i < dim ; i++) |
62 | { |
63 | boost::fusion::at_c<x>(data)[i] = boost::fusion::at_c<x>(sph.data)[i]; |
64 | } |
65 | |
66 | boost::fusion::at_c<r>(data) = boost::fusion::at_c<r>(sph.data); |
67 | } |
68 | |
69 | /*! \brief Sphere constructor |
70 | * |
71 | * Sphere constructor |
72 | * |
73 | * \tparam k dimensionality of the center point (and the sphere) |
74 | * \param c center point |
75 | * \param radius |
76 | * |
77 | */ |
78 | template<unsigned int k> |
79 | Sphere(boost::fusion::vector<T[k]> & c, T radius) |
80 | { |
81 | // Copy the center |
82 | for (int i = 0 ; i < dim ; i++) |
83 | { |
84 | boost::fusion::at_c<x>(data)[i] = boost::fusion::at_c<x>(c)[i]; |
85 | } |
86 | |
87 | boost::fusion::at_c<r>(data) = radius; |
88 | } |
89 | |
90 | /*! \brief Sphere constructor |
91 | * |
92 | * Sphere constructor |
93 | * |
94 | * \tparam k dimensionality of the center point (and the sphere) |
95 | * \param c center point |
96 | * \param radius |
97 | * |
98 | */ |
99 | Sphere(Point<dim,double> & c, T radius) |
100 | { |
101 | // Copy the center |
102 | for (int i = 0 ; i < dim ; i++) |
103 | { |
104 | boost::fusion::at_c<x>(data)[i] = c.get(i); |
105 | } |
106 | |
107 | boost::fusion::at_c<r>(data) = radius; |
108 | } |
109 | |
110 | /*! \brief Get the radius of the sphere |
111 | * |
112 | * \return the radius of the sphere |
113 | * |
114 | */ |
115 | __device__ __host__ T radius() const |
116 | { |
117 | return boost::fusion::at_c<r>(data); |
118 | } |
119 | |
120 | /*! \brief Check if a point is inside |
121 | * |
122 | * \tparam distance distance functor used to calculate the distance two points |
123 | * \param p Point to check if it is inside |
124 | * |
125 | * \return true if the point is inside |
126 | * |
127 | */ |
128 | __device__ __host__ bool isInside(Point<dim,T> p) const |
129 | { |
130 | T dist = 0.0; |
131 | |
132 | // calculate the distance of the center from the point |
133 | |
134 | for (int i = 0; i < dim ; i++) |
135 | { |
136 | dist += (boost::fusion::at_c<x>(data)[i] - p.get(i) )*(boost::fusion::at_c<x>(data)[i] - p.get(i) ); |
137 | } |
138 | |
139 | // Check if the distance is smaller than the radius |
140 | |
141 | if (dist <= boost::fusion::at_c<r>(data)*boost::fusion::at_c<r>(data)) |
142 | {return true;} |
143 | |
144 | |
145 | return false; |
146 | } |
147 | |
148 | /*! \brief Check if a point is inside |
149 | * |
150 | * \tparam distance distance functor used to calculate the distance two points |
151 | * \param p Point to check if it is inside |
152 | * |
153 | * \return true if the point is inside |
154 | * |
155 | */ |
156 | template<typename Distance> |
157 | __device__ __host__ bool isInside(Point<dim,T> p) const |
158 | { |
159 | T dist = 0.0; |
160 | |
161 | // Object to calculate distances |
162 | Distance d; |
163 | |
164 | // calculate the distance of the center from the point |
165 | |
166 | for (int i = 0; i < dim ; i++) |
167 | { |
168 | dist += d.accum_dist(boost::fusion::at_c<x>(data)[i],p.get(i) ); |
169 | } |
170 | |
171 | // Check if the distance is smaller than the radius |
172 | |
173 | if (dist <= boost::fusion::at_c<r>(data)) |
174 | {return true;} |
175 | |
176 | |
177 | return false; |
178 | } |
179 | |
180 | /*! \brief Is the point inside the sphere |
181 | * |
182 | * \param pnt check if the point is inside |
183 | * \return true if it is inside |
184 | * |
185 | */ |
186 | |
187 | template<typename Distance> bool |
188 | __device__ __host__ isInside(float * pnt) const |
189 | { |
190 | T dist = 0.0; |
191 | |
192 | // Object to calculate distances |
193 | Distance d; |
194 | |
195 | // calculate the distance of the center from the point |
196 | |
197 | for (int i = 0; i < dim ; i++) |
198 | { |
199 | dist += d.accum_dist(boost::fusion::at_c<x>(data)[i],pnt[i],i); |
200 | } |
201 | |
202 | // Check if the distance is smaller than the radius |
203 | |
204 | if (dist <= boost::fusion::at_c<r>(data)) |
205 | {return true;} |
206 | |
207 | return false; |
208 | } |
209 | |
210 | /*! \brief Return the distance from the surface |
211 | * |
212 | * \param p point |
213 | * \return the distance from the surface. The sign indicate if is outside or inside the shape |
214 | * |
215 | */ |
216 | __device__ __host__ T distance(Point<dim,T> & p) const |
217 | { |
218 | T dist = 0.0; |
219 | |
220 | // calculate the distance of the center from the point |
221 | |
222 | for (int i = 0; i < dim ; i++) |
223 | { |
224 | dist += (boost::fusion::at_c<x>(data)[i] - p.get(i))*(boost::fusion::at_c<x>(data)[i] - p.get(i)); |
225 | } |
226 | |
227 | return sqrt(dist) - radius(); |
228 | } |
229 | }; |
230 | |
231 | #endif |
232 | |