vgl_sphere_3d.hxx
Go to the documentation of this file.
1 #ifndef vgl_sphere_3d_hxx_
2 #define vgl_sphere_3d_hxx_
3 //:
4 // \file
5 // \brief a sphere in 3D nonhomogeneous space
6 // \author Ian Scott
7 
8 #include <cmath>
9 #include <iostream>
10 #include "vgl_sphere_3d.h"
11 #ifdef _MSC_VER
12 # include <vcl_msvc_warnings.h>
13 #endif
14 #include <vgl/vgl_point_3d.h>
15 #include <vgl/vgl_closest_point.h>
17 
18 
19 //: Return true iff the point p is inside (or on) this sphere
20 template <class T>
22 {
23  return r_ >= 0 && (p-c_).sqr_length() <= r_*r_;
24 }
25 
26 
27 //: Calculate the end points of a line clipped by this sphere.
28 // \return true if any of the line touches the sphere.
29 template <class T>
31  vgl_point_3d<T> &p1, vgl_point_3d<T> &p2) const
32 {
33  // The empty sphere does not intersect anything:
34  if (r_ < 0) return false;
35 
37 
38  T cp_sqr_len = (cp - c_).sqr_length();
39  if (cp_sqr_len > r_*r_) return false;
40  double arg = static_cast<double>(r_*r_ - cp_sqr_len);//for VC10
41  T half_chord_len = static_cast<T>(std::sqrt(arg));
42 
43  vgl_vector_3d<T> linevec = line.direction();
44  linevec *= half_chord_len / linevec.length();
45 
46  p1 = cp - linevec;
47  p2 = cp + linevec;
48 
49  return true;
50 }
51 
52 
53 //: Writes "<vgl_sphere_3d centre=vgl_point_3d<x,y,z> radius=r)>" to stream
54 template <class T>
55 std::ostream& vgl_sphere_3d<T>::print(std::ostream& os) const
56 {
57  return os << "<vgl_sphere_3d centre=" << c_
58  << "radius=" << r_ << '>';
59 }
60 
61 
62 //: Read from stream, possibly with formatting.
63 // Either just reads 4 blank-separated numbers,
64 // or reads 4 comma-separated numbers,
65 // or reads 4 numbers in parenthesized form "(123, 321, 567, 890)"
66 template <class T>
67 std::istream& vgl_sphere_3d<T>::read(std::istream& is)
68 {
69  if (! is.good()) return is; // (TODO: should throw an exception)
70  bool paren = false;
71  T cx, cy, cz, r;
72  is >> std::ws; // jump over any leading whitespace
73  if (is.eof()) return is; // nothing to be set because of EOF (TODO: should throw an exception)
74  if (is.peek() == '(') { is.ignore(); paren=true; }
75  is >> std::ws >> cx >> std::ws;
76  if (is.eof()) return is;
77  if (is.peek() == ',') is.ignore();
78  is >> std::ws >> cy >> std::ws;
79  if (is.eof()) return is;
80  if (is.peek() == ',') is.ignore();
81  is >> std::ws >> cz >> std::ws;
82  if (is.eof()) return is;
83  if (is.peek() == ',') is.ignore();
84  is >> std::ws >> r >> std::ws;
85  if (paren) {
86  if (is.eof()) return is;
87  if (is.peek() == ')') is.ignore();
88  else return is; // closing parenthesis is missing (TODO: throw an exception)
89  }
90  set_centre(vgl_point_3d<T>(cx,cy,cz));
91  set_radius(r);
92  return is;
93 }
94 
95 template <class Type>
96 void vgl_sphere_3d<Type>::spherical_to_cartesian(Type elevation_rad, Type azimuth_rad,
97  Type& x, Type& y, Type& z) const{
98 
99  double el = static_cast<double>(elevation_rad), az = static_cast<double>(azimuth_rad);
100  double cx = static_cast<double>(c_.x()),cy =static_cast<double>(c_.y()), cz = static_cast<double>(c_.z());
101  double r = static_cast<double>(r_);
102  double se = std::sin(el), ce = std::cos(el);
103  double sa = std::sin(az), ca = std::cos(az);
104 
105  x = static_cast<Type>((r*se*ca)+cx);
106  y = static_cast<Type>((r*se*sa)+cy);
107  z = static_cast<Type>((r*ce)+cz);
108 
109 }
110 
111 template <class Type>
112 void vgl_sphere_3d<Type>::spherical_to_cartesian(Type elevation_rad, Type azimuth_rad, vgl_point_3d<Type>& pt) const
113 {
114 
115  Type x, y, z;
116  spherical_to_cartesian(elevation_rad, azimuth_rad, x, y, z);
117  pt.set(x, y, z);
118 
119 }
120 template <class Type>
121 void vgl_sphere_3d<Type>::cartesian_to_spherical(Type x, Type y, Type z, Type& elevation_rad, Type& azimuth_rad) const{
122  double xd = static_cast<double>(x-c_.x()), yd = static_cast<double>(y-c_.y()), zd = static_cast<double>(z-c_.z());
123  double r = std::sqrt(xd*xd + yd*yd +zd*zd);
124  elevation_rad = static_cast<Type>(std::acos(zd/r));
125  azimuth_rad = static_cast<Type>(std::atan2(yd,xd));
126 }
127 template <class Type>
128 void vgl_sphere_3d<Type>::cartesian_to_spherical(vgl_point_3d<Type> const& pt, Type& elevation_rad, Type& azimuth_rad) const{
129  return cartesian_to_spherical(pt.x(), pt.y(), pt.z(),elevation_rad,azimuth_rad);
130 }
131 
132 //: Writes "<vgl_sphere_3d centre=vgl_point_3d<x,y,z> radius=r)>" to stream
133 template <class T>
134 std::ostream& operator<<(std::ostream& os, const vgl_sphere_3d<T>& sph)
135 {
136  return sph.print(os);
137 }
138 
139 
140 //: Read from stream, possibly with formatting.
141 // Either just reads 4 blank-separated numbers,
142 // or reads 4 comma-separated numbers,
143 // or reads 4 numbers in parenthesized form "(123, 321, 567, 890)"
144 template <class T>
145 std::istream& operator>>(std::istream& is, vgl_sphere_3d<T>& sph)
146 {
147  return sph.read(is);
148 }
149 
150 
151 #undef VGL_SPHERE_3D_INSTANTIATE
152 #define VGL_SPHERE_3D_INSTANTIATE(T) \
153 template class vgl_sphere_3d<T >; \
154 template std::ostream& operator<<(std::ostream&, vgl_sphere_3d<T >const&); \
155 template std::istream& operator>>(std::istream&, vgl_sphere_3d<T >&)
156 
157 
158 #endif // vgl_sphere_3d_hxx_
vgl_point_2d< T > vgl_closest_point(vgl_line_2d< T > const &l, vgl_point_2d< T > const &p)
Return the point on the given line closest to the given point.
vgl_vector_3d< Type > direction() const
Return the direction vector of this line (not normalised - but perhaps it should be,...
A class to hold a non-homogeneous representation of a 3D line.
Definition: vgl_fwd.h:17
vgl_point_3d< Type > c_
centre
Definition: vgl_sphere_3d.h:20
Set of closest-point functions.
std::ostream & print(std::ostream &os) const
Writes "<vgl_sphere_3d centre=vgl_point_3d<x,y,z> radius=r)>" to stream.
a point in 3D nonhomogeneous space
double length() const
Return the length of this vector.
a sphere in 3D nonhomogeneous space
T sqr_length(v const &a)
Return the squared length of a vector.
Definition: vgl_vector_2d.h:98
Type r_
radius
Definition: vgl_sphere_3d.h:21
Direction vector in Euclidean 3D space, templated by type of element.
Definition: vgl_fwd.h:13
bool clip(const vgl_line_3d_2_points< Type > &line, vgl_point_3d< Type > &p1, vgl_point_3d< Type > &p2) const
Calculate the end points of a line clipped by this sphere.
non-homogeneous 3D line, represented by 2 points.
bool contains(vgl_point_3d< Type > const &p) const
Return true iff the point p is inside (or on) this sphere.