mt
 All Classes Files Functions Enumerations Groups Pages
circle3.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_CIRCLE3_H
25 #define MT_CIRCLE3_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/plane3.h>
34 #include <mt/point3.h>
35 #include <mt/scalar.h>
36 #include <mt/sphere3.h>
37 #include <mt/unit3.h>
38 #include <mt/vector3.h>
39 
40 
42 
43 namespace mt
44 {
45 
46 
48 
51 
65 
66 class Circle3
67 {
68 public:
69 
70 // LIFECYCLE
71 
73  Circle3();
74 
78  Circle3(const Point3& point,
79  const Scalar& radius,
80  const Unit3& normal);
81 
85  Circle3(const Sphere3& sphere, const Plane3& plane);
86 
87  // Compiler generated copy constructor is being used
88 
89  // Compiler generated destructor is being used
90 
91 
92 // OPERATORS
93 
94  // Compiler generated assignment operator is being used
95 
96  bool operator==(const Circle3& c) const;
97  bool operator!=(const Circle3& c) const;
98 
99 // OPERATIONS
100 
102  Point3 project(const Point3& p) const;
103 
105  Scalar distance(const Point3& p) const;
106 
107 // ACCESS
108 
109  Point3 getCenter() const;
110  Point3& getCenterRef();
111  const Point3& getCenterRef() const;
112 
113  Scalar getRadius() const;
114  Scalar& getRadiusRef();
115  const Scalar& getRadiusRef() const;
116 
117  Unit3 getNormal() const;
118  Unit3& getNormalRef();
119  const Unit3& getNormalRef() const;
120 
121  Plane3 getSupportPlane() const;
122 
123  void setCenter(const Point3& center);
124 
128  void setRadius(const Scalar& radius);
129 
130  void setNormal(const Unit3& normal);
131 
135  void setValue(const Point3& center,
136  const Scalar& radius,
137  const Unit3& normal);
138 
139 
140 // INQUIRY
141 
143  bool isSingular() const;
144 
145 
146 private:
147 
148 // MEMBERS
149 
151 Point3 m_center;
152 
154 Scalar m_radius;
155 
157 Unit3 m_normal;
158 
159 };
160 
161 
163 
164 // OPERATORS
165 
166 std::ostream& operator<<(std::ostream& os,
167  const Circle3& c);
168 
169 
170 // FUNCTIONS
171 
173 Point3 project(const Point3& p,
174  const Circle3& c);
175 
177 Scalar distance(const Point3& p,
178  const Circle3& c);
179 
181 Scalar distance(const Circle3& s,
182  const Point3& c);
183 
184 
186 
187 // LIFECYCLE
188 
190 
191  m_center(0.0, 0.0, 0.0),
192  m_radius(1.0),
193  m_normal(0.0, 0.0, 1.0) {}
194 
195 
196 inline Circle3::Circle3(const Point3& center,
197  const Scalar& radius,
198  const Unit3& normal) :
199 
200  m_center(center),
201  m_radius(abs(radius)),
202  m_normal(normal) {}
203 
204 
205 inline Circle3::Circle3(const Sphere3& sphere, const Plane3& plane)
206 {
207  // Sphere parameters
208  const Point3 center(sphere.getCenter());
209  const Scalar radius(sphere.getRadius());
210 
211  // Projection of sphere center on plane
212  const Point3 proj_center(plane.project(center));
213 
214  // Distance from sphere center to plane
215  const Scalar dist(length(proj_center - center));
216 
217  // Checks that plane and sphere intersect
218  util::Assert(dist <= radius, Exception("Cannot construct circle, \
219 input plane and sphere do not intersect"));
220 
221  // Constructs circle
222  const Scalar circle_radius(sqrt(sq(radius) - sq(dist)));
223  setValue(proj_center,
224  circle_radius,
225  plane.getNormal());
226 
227 }
228 
229 
230 // OPERATORS
231 
232 inline bool Circle3::operator==(const Circle3& c) const
233 {
234  return (m_center == c.m_center) &&
235  (m_radius == c.m_radius) &&
236  (m_normal == c.m_normal || m_normal == -c.m_normal);
237 }
238 
239 
240 inline bool Circle3::operator!=(const Circle3& c) const
241 {
242  return !(*this == c);
243 }
244 
245 
246 // OPERATIONS
247 
248 inline Point3 Circle3::project(const Point3& p) const
249 {
250  // Projection of input point on circle support plane
251  const Plane3 sup = getSupportPlane();
252  Point3 proj_p(sup.project(p));
253 
254  // If the point to be projected coincides with circle center, its value is
255  // perturbed to obtain a particular projection point.
256  const value_t ep = std::numeric_limits<value_t>::epsilon();
257  if (getValue(m_center.distance(proj_p)) < ep)
258  {
259  // Perturbation vector (its direction is perpendicular to circle normal)
260  const Vector3 pert = Scalar(1000.0) * ep * sup.getSupportVector();
261  proj_p += pert;
262  }
263 
264  if (m_radius == Scalar(0.0))
265  {
266  // Singular sphere
267  return m_center;
268  }
269  else
270  {
271  // Non-singular circle
272  const Unit3 dist_center(proj_p - m_center);
273  return m_center + m_radius * dist_center;
274  }
275 }
276 
277 
278 inline Scalar Circle3::distance(const Point3& p) const
279 {
280  // Projection of input point on circle support plane
281  const Plane3 sup = getSupportPlane();
282  const Point3 proj_p(sup.project(p));
283 
284  if (proj_p != m_center)
285  {
286  return length(p - project(p));
287  }
288  else {
289  const Scalar proj_p_dist(sup.distance(p));
290  return sqrt(sq(m_radius) + sq(proj_p_dist));
291  }
292 }
293 
294 
295 // ACCESS
296 
297 inline Point3 Circle3::getCenter() const
298 {
299  return m_center;
300 }
301 
302 
303 inline Point3& Circle3::getCenterRef()
304 {
305  return m_center;
306 }
307 
308 
309 inline const Point3& Circle3::getCenterRef() const
310 {
311  return m_center;
312 }
313 
314 
315 inline Scalar Circle3::getRadius() const
316 {
317  return m_radius;
318 }
319 
320 
321 inline Scalar& Circle3::getRadiusRef()
322 {
323  return m_radius;
324 }
325 
326 
327 inline const Scalar& Circle3::getRadiusRef() const
328 {
329  return m_radius;
330 }
331 
332 
333 inline Unit3 Circle3::getNormal() const
334 {
335  return m_normal;
336 }
337 
338 
339 inline Unit3& Circle3::getNormalRef()
340 {
341  return m_normal;
342 }
343 
344 
345 inline const Unit3& Circle3::getNormalRef() const
346 {
347  return m_normal;
348 }
349 
350 
351 inline Plane3 Circle3::getSupportPlane() const
352 {
353  return Plane3(m_normal, m_center);
354 }
355 
356 
357 inline void Circle3::setCenter(const Point3& center)
358 {
359  m_center = center;
360 }
361 
362 
363 inline void Circle3::setRadius(const Scalar& radius)
364 {
365  m_radius = abs(radius);
366 }
367 
368 
369 inline void Circle3::setNormal(const Unit3& normal)
370 {
371  m_normal = normal;
372 }
373 
374 
375 inline void Circle3::setValue(const Point3& center,
376  const Scalar& radius,
377  const Unit3& normal)
378 {
379  m_center = center;
380  m_radius = abs(radius);
381  m_normal = normal;
382 }
383 
384 
385 // INQUIRY
386 
387 inline bool Circle3::isSingular() const
388 {
389  return m_radius == Scalar(0.0);
390 }
391 
392 
394 
395 // OPERATORS
396 
397 inline std::ostream& operator<<(std::ostream& os,
398  const Circle3& c)
399 {
400  return os << "center: " << c.getCenter() << ' '
401  << "radius: " << c.getRadius() << ' '
402  << "normal: " << c.getNormal();
403 }
404 
405 
406 // FUNCTIONS
407 
408 inline Point3 project(const Point3& p,
409  const Circle3& c)
410 {
411  return c.project(p);
412 }
413 
414 
415 inline Scalar distance(const Point3& p,
416  const Circle3& c)
417 {
418  return c.distance(p);
419 }
420 
421 
422 inline Scalar distance(const Circle3& c,
423  const Point3& p)
424 {
425  return c.distance(p);
426 }
427 
428 } // mt
429 
430 #endif // MT_CIRCLE3_H