core/vgl/vgl_1d_basis.h
Go to the documentation of this file.
00001 // This is core/vgl/vgl_1d_basis.h
00002 #ifndef vgl_1d_basis_h_
00003 #define vgl_1d_basis_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007 //:
00008 // \file
00009 // \brief storage for 3 collinear points to serve as 1-D projective basis
00010 //
00011 // vgl_1d_basis<T> is a class templated on the point type that
00012 // will be stored.  Typically, T will be vgl_point_2d<double> or
00013 // vgl_homg_point_2d<int> or even vgl_line_2d<float> or vgl_point_3d<T>.
00014 //
00015 // This class stores three unequal collinear points and will use these to
00016 // define a projection from e.g. 2d points on a line to a 1-dimensional
00017 // projective space: the first point receives coordinates (0,1), the second
00018 // one (1,0), and the third one (the unit point) coordinates (1,1).
00019 //
00020 // Note that this class can also be used for ``projecting'' from e.g.
00021 // vgl_homg_point_1d<float> or vgl_point_1d<int> to vgl_homg_point_1d<double>,
00022 // i.e., a kind of type casting operation, by passing it the homogeneous
00023 // points (0,1), (1,0) and (1,1).  Note that the destination space is
00024 // always vgl_homg_point_1d<double>.
00025 //
00026 // The only conditions on template type T are the following:
00027 // - It must know the concept of collinearity, viz. there must be a function
00028 //   ``bool collinear(T,T,T)''.
00029 //   (This is not necessary when using the constructor with two arguments.)
00030 // - There must be a function ``double cross_ratio(T,T,T,T)'', or alternatively
00031 //   (when using the constructor with two arguments) there must be a function
00032 //   ``double ratio(T,T,T)''.  These functions should return 0 if the last
00033 //   argument equals the 2-but-last and 1 if it equals the 1-but-last.
00034 //
00035 // These conditions are satisfied for the vgl_point_[23]d<Type> and
00036 // vgl_homg_point_[123]d<Type> classes.  For concurrent vgl_line_2d's
00037 // the method project() has to be specialised (which is easily done by
00038 // taking its intersection with the line at infinity!)
00039 //
00040 // \warning the C++ standard requires that these functions are
00041 // declared before they are used, which, for this, means in the
00042 // definition of the functions in the .txx file. So, for maximum
00043 // portability, make sure they are at least declared before the .txx
00044 // file is included.
00045 //
00046 // \author Peter Vanroose
00047 // \date   7 July, 2001
00048 //
00049 // \verbatim
00050 // Modifications
00051 //   Feb.2002 - Peter Vanroose - brief doxygen comment placed on single line
00052 // \endverbatim
00053 
00054 #include <vgl/vgl_fwd.h>
00055 #include <vgl/vgl_homg_point_1d.h>
00056 #include <vcl_iosfwd.h>
00057 #include <vcl_cassert.h>
00058 
00059 //----------------------------------------------------------------------
00060 
00061 //: Storage for 3 collinear points to serve as 1-D projective basis.
00062 // This class is templated on the point type that will be stored.
00063 // Typically, T will be vgl_point_2d<double> or
00064 // vgl_homg_point_2d<int> or even vgl_line_2d<float> or vgl_point_3d<T>.
00065 //
00066 // This class stores three unequal collinear points and will use these to
00067 // define a projection from e.g. 2d points on a line to a 1-dimensional
00068 // projective space: the first point receives coordinates (0,1), the second
00069 // one (the unit point) (1,1), and the third one (point at infinity) (1,0).
00070 //
00071 // Note that this class can also be used for ``projecting'' from e.g.
00072 // vgl_homg_point_1d<float> or vgl_point_1d<int> to vgl_homg_point_1d<double>,
00073 // i.e., a kind of type casting operation, by passing it the homogeneous
00074 // points (0,1), (1,1) and (1,0).  Note that the destination space is
00075 // always vgl_homg_point_1d<double>.
00076 //
00077 // The only conditions on template type T are the following:
00078 // - It must know the concept of collinearity, viz. there must be a function
00079 //   ``bool collinear(T,T,T)''.
00080 //   (This is not necessary when using the constructor with two arguments.)
00081 // - There must be a function ``double cross_ratio(T,T,T,T)'', or alternatively
00082 //   (when using the constructor with two arguments) there must be a function
00083 //   ``double ratio(T,T,T)''.  These functions should return 0 if the last
00084 //   argument equals the 2-but-last and 1 if it equals the 1-but-last.
00085 //
00086 // These conditions are satisfied for the vgl_point_[23]d<Type> and
00087 // vgl_homg_point_[123]d<Type> classes.  For concurrent vgl_line_2d's
00088 // the method project() has to be specialised (which is easily done by
00089 // taking its intersection with the line at infinity!)
00090 //
00091 template <class T>
00092 class vgl_1d_basis
00093 {
00094   // Data members are private:
00095   T origin_;    //!< The point to be mapped to homogeneous (0,1)
00096   T unity_;     //!< The point to be mapped to homogeneous (1,1)
00097   T inf_pt_;    //!< The point to be mapped to homogeneous (1,0)
00098   bool affine_; //!< normally false; if true, inf_pt_ is not used: affine basis
00099   // No usable default constructor:
00100   inline vgl_1d_basis() {}
00101 
00102  public:
00103   inline T origin() const { return origin_; }
00104   inline T unity() const { return unity_; }
00105   inline T inf_pt() const { assert(!affine_); return inf_pt_; }
00106   inline bool affine() const { return affine_; }
00107   inline bool projective() const { return !affine_; }
00108 
00109   //: Construct from three collinear points (projective basis).
00110   // It will serve as origin (0,1), unity (1,1) and point at infinity (1,0).
00111   // The points must be collinear, and different from each other.
00112   //
00113   // Note that there is no valid default constructor, since any sensible default
00114   // heavily depends on the structure of the point class T, the template type.
00115   //
00116   // Note that there is no way to overwrite an existing vgl_basis_1d;
00117   // just create a new one if you need a different one.
00118   // Hence it is not possible to read a vgl_basis_1d from stream with >>.
00119   //
00120   vgl_1d_basis(T const& o, T const& u, T const& i);
00121 
00122   //: Construct from two points (affine basis).
00123   // It will serve as origin (0,1) and unity point (1,1).
00124   // The points must be different from each other, and not at infinity.
00125   // This creates an affine basis, i.e., the point at infinity of the basis
00126   // will be the point at infinity of the line o-u in the source space.
00127   vgl_1d_basis(T const& o, T const& u);
00128 
00129   //: Projection from a point in the source space to a 1-D homogeneous point
00130   vgl_homg_point_1d<double> project(T const& p);
00131 };
00132 
00133 //  +-+-+ 1d_basis simple I/O +-+-+
00134 
00135 //: Write "<vgl_1d_basis o u i> " to stream
00136 // \relatesalso vgl_1d_basis
00137 template <class T> vcl_ostream& operator<<(vcl_ostream& s, vgl_1d_basis<T> const&);
00138 
00139 #define VGL_1D_BASIS_INSTANTIATE(T) extern "please include vgl/vgl_1d_basis.txx first"
00140 
00141 #endif // vgl_1d_basis_h_