mt
 All Classes Files Functions Enumerations Groups Pages
cylinder3.h
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2006 by Adolfo Rodriguez *
3  * adolfo.rodriguez@upc.edu *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ***************************************************************************/
20 
22 
23 // HEADER GUARD
24 #ifndef MT_CYLINDER3_H
25 #define MT_CYLINDER3_H
26 
27 // C++ STANDARD HEADERS
28 #include <iostream>
29 #include <limits>
30 
31 // MT LIBRARY HEADERS
32 #include <mt/exception.h>
33 #include <mt/line3.h>
34 #include <mt/point3.h>
35 #include <mt/scalar.h>
36 #include <mt/vector3.h>
37 
38 
40 
41 namespace mt
42 {
43 
44 
46 
49 
61 
62 class Cylinder3
63 {
64 public:
65 
66 // LIFECYCLE
67 
70  Cylinder3();
71 
75  Cylinder3(const Line3& axis, const Scalar& radius);
76 
77  // Compiler generated copy constructor is being used
78 
79  // Compiler generated destructor is being used
80 
81 
82 // OPERATORS
83 
84  // Compiler generated assignment operator is being used
85 
86  bool operator==(const Cylinder3& c) const;
87  bool operator!=(const Cylinder3& c) const;
88 
89 // OPERATIONS
90 
92  Point3 project(const Point3& p) const;
93 
99  Scalar distance(const Point3& p) const;
100 
101 // ACCESS
102 
103  Line3 getAxis() const;
104  Line3& getAxisRef();
105  const Line3& getAxisRef() const;
106 
107  Scalar getRadius() const;
108  Scalar& getRadiusRef();
109  const Scalar& getRadiusRef() const;
110 
111  void setAxis(const Line3& axis);
112 
116  void setRadius(const Scalar& radius);
117 
121  void setValue(const Line3& axis, const Scalar& radius);
122 
123 
124 // INQUIRY
125 
127  bool isSingular() const;
128 
129 
130 private:
131 
132 // MEMBERS
133 
135 Line3 m_axis;
136 
138 Scalar m_radius;
139 
140 };
141 
142 
144 
145 // OPERATORS
146 
147 std::ostream& operator<<(std::ostream& os,
148  const Cylinder3& c);
149 
150 
151 // FUNCTIONS
152 
154 Point3 project(const Point3& p,
155  const Cylinder3& c);
156 
158 Scalar distance(const Point3& p,
159  const Cylinder3& c);
160 
162 Scalar distance(const Sphere3& s,
163  const Cylinder3& c);
164 
165 
167 
168 // LIFECYCLE
169 
171 
172  m_axis(Line3()),
173  m_radius(1.0) {}
174 
175 inline Cylinder3::Cylinder3(const Line3& axis, const Scalar& radius) :
176 
177  m_axis(axis),
178  m_radius(abs(radius)) {}
179 
180 
181 // OPERATORS
182 
183 inline bool Cylinder3::operator==(const Cylinder3& c) const
184 {
185  return (m_axis == c.m_axis) && (m_radius == c.m_radius);
186 }
187 
188 
189 inline bool Cylinder3::operator!=(const Cylinder3& c) const
190 {
191  return !(*this == c);
192 }
193 
194 
195 // OPERATIONS
196 
197 inline Point3 Cylinder3::project(const Point3& p) const
198 {
199  // Projection of input point on cylinder axis
200  Point3 proj_axis(m_axis.project(p));
201 
202  // If the point to be projected coincides with the cylinder axis, its value is
203  // perturbed to obtain a particular projection point.
204  const value_t ep = std::numeric_limits<value_t>::epsilon();
205  if (getValue(m_axis.distance(proj_axis)) < ep)
206  {
207  // Perturbation vector (its direction is perpendicular to cylinder axis)
208  const Plane3 P(m_axis.getDirection(), 0.0);
209  const Vector3 pert = Scalar(1000.0) * ep * P.getSupportVector();
210  proj_axis += pert;
211  }
212 
213  // Projection of point on cylinder
214  if (m_radius == Scalar(0.0))
215  {
216  // Singular cylinder
217  return proj_axis;
218  }
219  else
220  {
221  // Non-singular cylinder
222  const Unit3 dist_axis(p - proj_axis);
223  return proj_axis + m_radius * dist_axis;
224  }
225 }
226 
227 
228 inline Scalar Cylinder3::distance(const Point3& p) const
229 {
230  // Projection of input point on cylinder axis
231  const Point3 proj_axis(m_axis.project(p));
232 
233  // Signed point-cylinder distance
234  const Scalar dist_axis(length(p - proj_axis));
235  return dist_axis - m_radius;
236 }
237 
238 
239 // ACCESS
240 
241 inline Line3 Cylinder3::getAxis() const
242 {
243  return m_axis;
244 }
245 
246 
247 inline Line3& Cylinder3::getAxisRef()
248 {
249  return m_axis;
250 }
251 
252 
253 inline const Line3& Cylinder3::getAxisRef() const
254 {
255  return m_axis;
256 }
257 
258 
259 inline Scalar Cylinder3::getRadius() const
260 {
261  return m_radius;
262 }
263 
264 
265 inline Scalar& Cylinder3::getRadiusRef()
266 {
267  return m_radius;
268 }
269 
270 
271 inline const Scalar& Cylinder3::getRadiusRef() const
272 {
273  return m_radius;
274 }
275 
276 
277 inline void Cylinder3::setAxis(const Line3& axis)
278 {
279  m_axis = axis;
280 }
281 
282 
283 inline void Cylinder3::setRadius(const Scalar& radius)
284 {
285  m_radius = abs(radius);
286 }
287 
288 
289 inline void Cylinder3::setValue(const Line3& axis, const Scalar& radius)
290 {
291  m_axis = axis;
292  m_radius = abs(radius);
293 }
294 
295 
296 // INQUIRY
297 
298 inline bool Cylinder3::isSingular() const
299 {
300  return m_radius == Scalar(0.0);
301 }
302 
303 
305 
306 // OPERATORS
307 
308 inline std::ostream& operator<<(std::ostream& os,
309  const Cylinder3& c)
310 {
311  return os << "axis: " << c.getAxis() << ' '
312  << "radius: " << c.getRadius();
313 }
314 
315 
316 // FUNCTIONS
317 
318 inline Point3 project(const Point3& p,
319  const Cylinder3& c)
320 {
321  return c.project(p);
322 }
323 
324 
325 inline Scalar distance(const Point3& p,
326  const Cylinder3& c)
327 {
328  return c.distance(p);
329 }
330 
331 
332 inline Scalar distance(const Cylinder3& c,
333  const Point3& p)
334 {
335  return c.distance(p);
336 }
337 
338 } // mt
339 
340 #endif // MT_CYLINDER3_H