Go to the documentation of this file.00001 #ifndef vgl_sphere_3d_txx_
00002 #define vgl_sphere_3d_txx_
00003 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00004 #pragma implementation
00005 #endif
00006
00007
00008
00009
00010
00011 #include "vgl_sphere_3d.h"
00012 #include <vcl_cmath.h>
00013 #include <vcl_iostream.h>
00014 #include <vgl/vgl_point_3d.h>
00015 #include <vgl/vgl_closest_point.h>
00016 #include <vgl/vgl_line_3d_2_points.h>
00017
00018
00019
00020 template <class T>
00021 bool vgl_sphere_3d<T>::contains(vgl_point_3d<T> const& p) const
00022 {
00023 return r_ >= 0 && (p-c_).sqr_length() <= r_*r_;
00024 }
00025
00026
00027
00028
00029 template <class T>
00030 bool vgl_sphere_3d<T>::clip(const vgl_line_3d_2_points<T> & line,
00031 vgl_point_3d<T> &p1, vgl_point_3d<T> &p2) const
00032 {
00033
00034 if (r_ < 0) return false;
00035
00036 vgl_point_3d<T> cp = vgl_closest_point(line, c_);
00037
00038 T cp_sqr_len = (cp - c_).sqr_length();
00039 if (cp_sqr_len > r_*r_) return false;
00040
00041 T half_chord_len = vcl_sqrt(r_*r_ - cp_sqr_len);
00042
00043 vgl_vector_3d<T> linevec = line.direction();
00044 linevec *= half_chord_len / linevec.length();
00045
00046 p1 = cp - linevec;
00047 p2 = cp + linevec;
00048
00049 return true;
00050 }
00051
00052
00053
00054 template <class T>
00055 vcl_ostream& vgl_sphere_3d<T>::print(vcl_ostream& os) const
00056 {
00057 return os << "<vgl_sphere_3d centre=" << c_
00058 << "radius=" << r_ << '>';
00059 }
00060
00061
00062 //: Read from stream, possibly with formatting.
00063 // Either just reads 4 blank-separated numbers,
00064 // or reads 4 comma-separated numbers,
00065 // or reads 4 numbers in parenthesized form "(123, 321, 567, 890)"
00066 template <class T>
00067 vcl_istream& vgl_sphere_3d<T>::read(vcl_istream& is)
00068 {
00069 if (! is.good()) return is; // (TODO: should throw an exception)
00070 bool paren = false;
00071 T cx, cy, cz, r;
00072 is >> vcl_ws; // jump over any leading whitespace
00073 if (is.eof()) return is; // nothing to be set because of EOF (TODO: should throw an exception)
00074 if (is.peek() == '(') { is.ignore(); paren=true; }
00075 is >> vcl_ws >> cx >> vcl_ws;
00076 if (is.eof()) return is;
00077 if (is.peek() == ',') is.ignore();
00078 is >> vcl_ws >> cy >> vcl_ws;
00079 if (is.eof()) return is;
00080 if (is.peek() == ',') is.ignore();
00081 is >> vcl_ws >> cz >> vcl_ws;
00082 if (is.eof()) return is;
00083 if (is.peek() == ',') is.ignore();
00084 is >> vcl_ws >> r >> vcl_ws;
00085 if (paren) {
00086 if (is.eof()) return is;
00087 if (is.peek() == ')') is.ignore();
00088 else return is; // closing parenthesis is missing (TODO: throw an exception)
00089 }
00090 set_centre(vgl_point_3d<T>(cx,cy,cz));
00091 set_radius(r);
00092 return is;
00093 }
00094
00095
00096 //: Writes "<vgl_sphere_3d centre=vgl_point_3d<x,y,z> radius=r)>" to stream
00097 template <class T>
00098 vcl_ostream& operator<<(vcl_ostream& os, const vgl_sphere_3d<T>& sph)
00099 {
00100 return sph.print(os);
00101 }
00102
00103
00104 //: Read from stream, possibly with formatting.
00105 // Either just reads 4 blank-separated numbers,
00106 // or reads 4 comma-separated numbers,
00107 // or reads 4 numbers in parenthesized form "(123, 321, 567, 890)"
00108 template <class T>
00109 vcl_istream& operator>>(vcl_istream& is, vgl_sphere_3d<T>& sph)
00110 {
00111 return sph.read(is);
00112 }
00113
00114
00115 #undef VGL_SPHERE_3D_INSTANTIATE
00116 #define VGL_SPHERE_3D_INSTANTIATE(T) \
00117 template class vgl_sphere_3d<T >; \
00118 template vcl_ostream& operator<<(vcl_ostream&, vgl_sphere_3d<T >const&); \
00119 template vcl_istream& operator>>(vcl_istream&, vgl_sphere_3d<T >&)
00120
00121
00122 #endif // vgl_sphere_3d_txx_