core/vgl/vgl_point_3d.txx
Go to the documentation of this file.
00001 // This is core/vgl/vgl_point_3d.txx
00002 #ifndef vgl_point_3d_txx_
00003 #define vgl_point_3d_txx_
00004 //:
00005 // \file
00006 
00007 #include "vgl_point_3d.h"
00008 #include <vgl/vgl_homg_point_3d.h>
00009 #include <vgl/vgl_plane_3d.h>
00010 #include <vgl/vgl_homg_plane_3d.h>
00011 
00012 #include <vcl_iostream.h>
00013 #include <vcl_iomanip.h>
00014 
00015 //: Construct from homogeneous point
00016 template <class Type>
00017 vgl_point_3d<Type>::vgl_point_3d(vgl_homg_point_3d<Type> const& p)
00018   : x_(p.x()/p.w()), y_(p.y()/p.w()), z_(p.z()/p.w()) // could be infinite!
00019 {
00020 }
00021 
00022 //: Construct from 3 planes (intersection).
00023 template <class Type>
00024 vgl_point_3d<Type>::vgl_point_3d(vgl_plane_3d<Type> const& pl1,
00025                                  vgl_plane_3d<Type> const& pl2,
00026                                  vgl_plane_3d<Type> const& pl3)
00027 {
00028   vgl_homg_plane_3d<Type> h1(pl1.nx(), pl1.ny(), pl1.nz(), pl1.d());
00029   vgl_homg_plane_3d<Type> h2(pl2.nx(), pl2.ny(), pl2.nz(), pl2.d());
00030   vgl_homg_plane_3d<Type> h3(pl3.nx(), pl3.ny(), pl3.nz(), pl3.d());
00031   vgl_homg_point_3d<Type> p(h1, h2, h3); // do homogeneous intersection
00032   set(p.x()/p.w(), p.y()/p.w(), p.z()/p.w()); // could be infinite!
00033 }
00034 
00035 template <class T>
00036 double cross_ratio(vgl_point_3d<T>const& p1, vgl_point_3d<T>const& p2,
00037                    vgl_point_3d<T>const& p3, vgl_point_3d<T>const& p4)
00038 {
00039   // least squares solution: (Num_x-CR*Den_x)^2 + (Num_y-CR*Den_y)^2 + (Num_z-CR*Den_z)^2 minimal.
00040   double Num_x = (p1.x()-p3.x())*(p2.x()-p4.x());
00041   double Num_y = (p1.y()-p3.y())*(p2.y()-p4.y());
00042   double Num_z = (p1.z()-p3.z())*(p2.z()-p4.z());
00043   double Den_x = (p1.x()-p4.x())*(p2.x()-p3.x());
00044   double Den_y = (p1.y()-p4.y())*(p2.y()-p3.y());
00045   double Den_z = (p1.z()-p4.z())*(p2.z()-p3.z());
00046   if (Den_x == Den_y && Den_y == Den_z) return (Num_x+Num_y+Num_z)/3/Den_x;
00047   else return (Den_x*Num_x+Den_y*Num_y+Den_z*Num_z)/(Den_x*Den_x+Den_y*Den_y+Den_z*Den_z);
00048 }
00049 
00050 //: Write "<vgl_point_3d x,y,z> " to stream
00051 template <class Type>
00052 vcl_ostream&  operator<<(vcl_ostream& s, vgl_point_3d<Type> const& p)
00053 {
00054   return s << "<vgl_point_3d "<< p.x() << ',' << p.y() << ',' << p.z() << "> ";
00055 }
00056 
00057 //: Read from stream, possibly with formatting
00058 //  Either just reads three blank-separated numbers,
00059 //  or reads three comma-separated numbers,
00060 //  or reads three numbers in parenthesized form "(123, 321, 567)"
00061 // \relatesalso vgl_point_3d
00062 template <class Type>
00063 vcl_istream& vgl_point_3d<Type>::read(vcl_istream& is)
00064 {
00065   if (! is.good()) return is; // (TODO: should throw an exception)
00066   bool paren = false;
00067   Type tx, ty, tz;
00068   is >> vcl_ws; // jump over any leading whitespace
00069   if (is.eof()) return is; // nothing to be set because of EOF (TODO: should throw an exception)
00070   if (is.peek() == '(') { is.ignore(); paren=true; }
00071   is >> vcl_ws >> tx >> vcl_ws;
00072   if (is.eof()) return is;
00073   if (is.peek() == ',') is.ignore();
00074   is >> vcl_ws >> ty >> vcl_ws;
00075   if (is.eof()) return is;
00076   if (is.peek() == ',') is.ignore();
00077   is >> vcl_ws >> tz >> vcl_ws;
00078   if (paren) {
00079     if (is.eof()) return is;
00080     if (is.peek() == ')') is.ignore();
00081     else                  return is; // closing parenthesis is missing (TODO: throw an exception)
00082   }
00083   set(tx,ty,tz);
00084   return is;
00085 }
00086 
00087 //: Read from stream, possibly with formatting
00088 //  Either just reads three blank-separated numbers,
00089 //  or reads three comma-separated numbers,
00090 //  or reads three numbers in parenthesized form "(123, 321, 567)"
00091 // \relatesalso vgl_point_3d
00092 template <class Type>
00093 vcl_istream&  operator>>(vcl_istream& is, vgl_point_3d<Type>& p)
00094 {
00095   return p.read(is);
00096 }
00097 
00098 #undef VGL_POINT_3D_INSTANTIATE
00099 #define VGL_POINT_3D_INSTANTIATE(T) \
00100 template class vgl_point_3d<T >; \
00101 template double cross_ratio(vgl_point_3d<T >const&, vgl_point_3d<T >const&, \
00102                             vgl_point_3d<T >const&, vgl_point_3d<T >const&); \
00103 template vcl_ostream& operator<<(vcl_ostream&, const vgl_point_3d<T >&); \
00104 template vcl_istream& operator>>(vcl_istream&, vgl_point_3d<T >&)
00105 
00106 #endif // vgl_point_3d_txx_