Go to Overview over all GrAL packages.
Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

Geometry/point-traits.h

Go to the documentation of this file.
00001 #ifndef NMWR_GB_POINT_TRAITS_H
00002 #define NMWR_GB_POINT_TRAITS_H
00003 
00004 
00005 
00006 // $LICENSE
00007 
00008 #include "Config/compiler-config.h"
00009 #include "Utility/pre-post-conditions.h"
00010 
00015 template<class P>
00016 struct point_traits {};
00017 
00018 // TODO: tags system is a mess!
00019 
00020 struct fixed_dimension_tag    {};
00021 struct variable_dimension_tag {};
00022 
00023 struct tag_unknown_dim {};
00024 //struct tag_runtime_dim {};
00025 struct tag1D : public fixed_dimension_tag {};
00026 struct tag2D : public fixed_dimension_tag {};
00027 struct tag3D : public fixed_dimension_tag {};
00028 struct tag4D : public fixed_dimension_tag {};
00029 
00030 template<unsigned N>
00031 struct dim_tag {
00032   enum { dim = N};
00033   typedef fixed_dimension_tag dimension_tag;
00034 };
00035 
00036 template<> struct dim_tag<1> { typedef tag1D dimension_tag;};
00037 template<> struct dim_tag<2> { typedef tag2D dimension_tag;};
00038 template<> struct dim_tag<3> { typedef tag3D dimension_tag;};
00039 template<> struct dim_tag<4> { typedef tag4D dimension_tag;};
00040 
00041 
00042 template<class POINT>
00043 struct point_traits_base 
00044 {
00045   typedef tag_unknown_dim dimension_tag;
00046   typedef POINT  Ptype;
00047 
00048 };
00049 
00050 // TODO: let all point_traits for fixed dimension types inherit this.
00051 template<class POINT, unsigned DIM>
00052 struct point_traits_fixed_dim 
00053   : public point_traits_base<POINT>
00054 {
00055   typedef dim_tag<N>                dimension_tag; 
00056   static unsigned Dim()             { return DIM;}
00057   static unsigned Dim(Ptype const&) { return DIM;}
00058   static void     ConstructWithDim(unsigned d, Ptype&)
00059     { REQUIRE(d == DIM, "Cannot construct: d = " << d << "; DIM = " << DIM,1);}
00060 };
00061 
00062 
00066 template<class REAL>
00067 struct real_point_traits : public point_traits_base<REAL> { 
00068   typedef REAL Ptype;
00069   typedef tag1D dimension_tag;
00070   typedef REAL component_type;
00071   typedef component_type value_type;
00072 
00073   static unsigned Dim(const Ptype&) { return 1;}
00074   static unsigned Dim() { return 1;}
00075   
00076   static Ptype Origin(unsigned) { return REAL(0.0);}
00077   static Ptype Origin()         { return REAL(0.0);}
00078   static component_type  x(const Ptype& p) {return p;}
00079   static component_type& x(      Ptype& p) {return p;}
00080   static component_type  y(const Ptype&) {return component_type(0.0);}
00081   static component_type  z(const Ptype&) {return component_type(0.0);}
00082 };
00083 
00084 template<>
00085 struct point_traits<float> 
00086   : public real_point_traits<float> {};
00087 
00088 template<>
00089 struct point_traits<double> 
00090   : public real_point_traits<double> {};
00091 
00092 
00093 
00094 
00095 template<class ARRAY, class COMPONENT, unsigned DIM>
00096 struct point_traits_fixed_size_array :
00097   public point_traits_base<ARRAY>
00098 {
00099   typedef ARRAY          Ptype;
00100   typedef COMPONENT      component_type;
00101   typedef component_type value_type;
00102   typedef dim_tag<DIM>::dimension_tag dimension_tag;
00103 
00104   static void ConstructWithDim(unsigned d, Ptype&)
00105     { REQUIRE(d == DIM, "Cannot construct! d = " << d 
00106               << ", DIM = " << DIM <<'\n',1);
00107     }
00108   static unsigned Dim(const Ptype&) { return DIM;}
00109   static unsigned Dim() { return DIM;}
00110   
00111   static int LowerIndex()             { return 0;}
00112   static int LowerIndex(Ptype const&) { return 0;}
00113   static int UpperIndex()             { return DIM-1;}
00114   static int UpperIndex(Ptype const&) { return DIM-1;}
00115 
00116 
00117   static Ptype Origin() {
00118     Ptype p; 
00119     for(unsigned i = 0; i < DIM; ++i) p[i] = component_type(0.0);
00120     return p;
00121   }
00122   static Ptype Origin(unsigned) { return Origin();}
00123 
00124 
00125   // should branch on DIM here.
00126   static component_type  x(const Ptype& p) {return p[0];}
00127   static component_type& x(      Ptype& p) {return p[0];}
00128   static component_type  y(const Ptype& p) {return p[1];}
00129   static component_type& y(      Ptype& p) {return p[1];}
00130   static component_type  z(const Ptype& p) {return p[2];}
00131   static component_type& z(      Ptype& p) {return p[2];}
00132 
00133 };
00134 
00135 
00136 template<class ARRAY, unsigned N>
00137 struct array_operators 
00138 {
00139   ARRAY      & to_derived()       { return static_cast<ARRAY&>(*this);}
00140   ARRAY const& to_derived() const { return static_cast<ARRAY const&>(*this);}
00141 
00142 
00143   ARRAY& operator-=(ARRAY const& rhs) {
00144     for(unsigned i  = 0; i < N; ++i) 
00145       to_derived()[i] -= rhs[i];
00146     return to_derived(); 
00147   }
00148   ARRAY operator-(ARRAY const& rhs) const {
00149     ARRAY lhs(to_derived());
00150     return lhs -= rhs;
00151   }
00152   ARRAY& operator+=(ARRAY const& rhs) {
00153     for(unsigned i  = 0; i < N; ++i) 
00154       to_derived()[i] += rhs[i];
00155     return to_derived(); 
00156   }
00157   ARRAY operator+(ARRAY const& rhs) const {
00158     ARRAY lhs(to_derived());
00159     return lhs += rhs;
00160   }
00161 
00162 };
00163 
00164 
00165 //----------------------------------------------------------------
00166 //
00167 // void assign_point(P & p, Q const& q);
00168 //
00169 // generic assignment operation
00170 // semantics: p = q
00171 // This could also be provided by a member template:
00172 //  template<class Q>
00173 //  P::operator=(Q const&);
00174 //
00175 //----------------------------------------------------------------
00176 
00177 template<class P, class Q>
00178 inline void assign_point(P      & p,
00179                          Q const& q) 
00180 {
00181  typedef point_traits<P> ptP;
00182  typedef point_traits<Q> ptQ;
00183 
00184  // if variable dimension: adapt dim of p, else this is a no-op.
00185  ptP::ConstructWithDim(ptQ::Dim(q), p); 
00186 
00187  
00188  REQUIRE( (ptP::Dim(p) == ptQ::Dim(q)), 
00189           "Cannot assign points of different dimension!" 
00190           << "(dim(p) = " << ptP::Dim(p)  << ", "
00191           << "(dim(q) = " << ptQ::Dim(q), 1);
00192  
00193  int iq = ptQ::LowerIndex(q); 
00194  int ip = ptP::LowerIndex(p);  
00195  for(; iq <= ptQ::UpperIndex(q); ++ip, ++iq)
00196    p[ip] = q[iq]; 
00197 }  
00198 
00199 // P = [b,e)
00200 template<class P, class T>
00201 inline void assign_point(P & p, T const* b, T const* e) 
00202 {
00203   REQUIRE( (e-b > 0), "invalid pointer range: b = " << b << "; e = " << e << "\n",1);
00204   typedef point_traits<P> ptP;
00205 
00206   // if variable dimension: adapt dim of p, else this is a no-op.
00207   ptP::ConstructWithDim(e-b,p);
00208 
00209   REQUIRE( ptP::Dim(p) == e-b, 
00210            "Cannot assign points of different dimension!" 
00211           << "(dim(p) = " << ptP::Dim(p)  << ", "
00212           << "e-p = " <<  e-p, 1);
00213 
00214   int ip = ptP::LowerIndex(p);  
00215   for(; b < e; ++ip, ++b)
00216     p[ip] = *b; 
00217 }  
00218 
00219 template<class P>
00220 inline void assign_point(P& p, P const& q) { p = q;}
00221 
00222 // these specializations should not be necessary!
00223 template<class P>
00224 inline void assign_point(float& p, P const& q) 
00225 
00226 { p = point_traits<P>::x(q);}
00227 
00228 inline void assign_point(float& p, float q) { p = q;}
00229 
00230 #endif

Copyright (c) Guntram Berti 1997-2002. See the GrAL Homepage for up-to-date information.

Generated at Tue Feb 26 15:57:27 2002 for Geometry by doxygen 1.2.11-20011104 written by Dimitri van Heesch, © 1997-2000