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

Geometry/algebraic-primitives.h

Go to the documentation of this file.
00001 #ifndef NMWR_GB_ALGEBRAIC_PRIMITIVES
00002 #define NMWR_GB_ALGEBRAIC_PRIMITIVES
00003 
00004 
00005 
00006 // $LICENSE
00007 
00008 #include <math.h>
00009 #include "Utility/pre-post-conditions.h"
00010 #include "Geometry/point-traits.h"
00011 
00012 //----------------------------------------------------------------
00013 //
00014 //  this file contains some generic implementations for 
00015 //  elementary algebraic & geometric operations,
00016 //  such as determinants or area-calculations.
00017 //
00018 //  class structure:
00019 //  
00020 //                + - - - ddp 2d - - - +
00021 //                |                    |
00022 //                + - - - ddp 3d - - - +
00023 //                |                    |
00024 // ap ---- ddp -- + - - - - - - - - - -+--- bap
00025 //
00026 // where:
00027 // ap  - algebraic_primitives:            user-interface class
00028 // bap - basic_algebraic_primitives:      non-dimension-dependent functions
00029 // ddp - dimension_dependent_primitives : bap + possible extensions for 2D/3D. 
00030 //       This class may be specialized for concrete POINT types.
00031 // ddp{2d,3d} - dimension_dependent_primitives_{2d,3d} : special functions
00032 //       for 2D or 3D. 
00033 //       This can be used to specialize ddp, e.g.:
00034 //       dimension_dependent_primitives<mypoint> : 
00035 //         public dimension_dependent_primitives_2d<mypoint> {};
00036 //
00037 //----------------------------------------------------------------
00038 
00039 
00040 
00041 
00042 template<class POINT>
00043 struct basic_algebraic_primitives : public point_traits<POINT> {
00044 
00045   typedef point_traits<POINT> pt;
00046   typedef typename pt::component_type scalar;
00047   typedef scalar   real; // should use scalar_traits<scalar>::real
00048   // anayway, some of the below are not correct for scalar = complex.
00049 
00050   static scalar sqr(scalar x) { return (x*x);}
00051 
00052   static scalar dot(const POINT& p, const POINT& q)
00053     {
00054       int d = Dim(p);
00055       int lp = LowerIndex(p);
00056       int lq = LowerIndex(q); 
00057       scalar sum = 0.0;
00058       for(int i = 0; i< d; i++)
00059         sum += p[lp+i]*q[lq+i];
00060       
00061       return sum;
00062     }
00063 
00064   static scalar distance2(const POINT& p1, const POINT& p2)
00065     {
00066       scalar sum = 0;
00067       for(int i = LowerIndex(p1); i<= UpperIndex(p1); i++)
00068         sum += sqr(p1[i]-p2[i]);
00069       return sum;
00070     }
00071 
00072   static scalar  distance(const POINT& p1, const POINT& p2)
00073     { return sqrt(distance2(p1,p2));}
00074 
00075   static scalar squared_norm_2(const POINT& p)
00076     {
00077       scalar sum = 0;
00078       typedef point_traits<POINT> traits;
00079       for(int i = traits::LowerIndex(p); i<= traits::UpperIndex(p); i++)
00080         sum += sqr(p[i]);
00081       return sum;
00082     }
00083 
00084   static real norm_2(const POINT& p) { return sqrt(squared_norm_2(p));}
00085   static POINT normalization(const POINT& p) { return(p/norm_2(p));}
00086   static void  normalize(POINT & p) { p = normalization(p);}
00087 
00088   static real norm_1(POINT const& p) {
00089     real sum = 0;
00090     for(int i = pt::LowerIndex(p); i <= pt::UpperIndex(p); ++i)
00091       sum += fabs(p[i]);
00092     return sum;
00093   }
00094 
00095   static real norm_infinity(POINT const& p) {
00096    real max_comp = 0;
00097    for(int i = pt::LowerIndex(p); i < pt::UpperIndex(p); ++i)
00098       max_comp = ( max_comp < fabs(p[i]) ? fabs(p[i]): max_comp);
00099    return max_comp;
00100   }
00101   // better: ?
00102   // static void normalize(POINT& p) { p *= 1.0/norm(p);}
00103 
00104   static real rel_diff(POINT const& p1, POINT const& p2)
00105     {
00106      POINT p(p1-p2);
00107      real result = norm_2(p);
00108      if(result != 0.0) {
00109        result /= std::max(norm_2(p1), norm_2(p2));
00110      }
00111      return result;
00112     }
00113 
00119   static  scalar cos_of_angle(const POINT& p, const POINT& q)
00120     {return (dot(p,q)/(norm_2(p)*norm_2(q)));}
00121 
00127   static  scalar angle(const POINT& p, const POINT& q)
00128     {return acos(cos_of_angle(p,q));}
00129 
00130 };
00131 
00132 
00133 
00135 //
00136 // dimension dependent functions 
00137 //
00139 
00140 
00141 
00142 #include "Geometry/primitives2d.h"
00143 #include "Geometry/primitives3d.h"
00144 
00145 
00146 template<class POINT, class DIM_TAG = tag_unknown_dim>
00147 struct dimension_dependent_primitives 
00148   : public basic_algebraic_primitives<POINT>  {};
00149 
00150 template<class POINT>
00151 struct dimension_dependent_primitives<POINT, tag2D>
00152   : public dimension_dependent_primitives_2d<POINT>  {};
00153 
00154 template<class POINT>
00155 struct dimension_dependent_primitives<POINT, tag3D>
00156   : public  dimension_dependent_primitives_3d<POINT>  {};
00157 
00158 template<class POINT>
00159 struct dimension_dependent_primitives<POINT, variable_dimension_tag>
00160   : public dimension_dependent_primitives_2d<POINT>,
00161     public dimension_dependent_primitives_3d<POINT>
00162   {};
00163 
00164 template<class POINT, class PT = point_traits<POINT> >
00165 struct algebraic_primitives 
00166   : public dimension_dependent_primitives
00167     <
00168      POINT,
00169      typename  PT::dimension_tag
00170     > 
00171 {};
00172 
00173 
00174 
00175 //-------------------------------------------------------------------------
00176 //
00177 // calculate centroid and area of a simple polygon, given by the vertices
00178 // [begin, end).
00179 // The centroid (or center of inertia) c of a domain D is defined by
00180 // \int_{D} x_i dx dy / area(D)
00181 //
00182 // This is adapted from GraphicsGems IV, centroid.c
00183 //
00184 //-------------------------------------------------------------------------
00185 
00186 template<class PIt, class Q>
00187 void get_polygon2d_center_and_area(PIt begin, PIt end, // in:  iterator over polygon vertices
00188                                    Q& center,          // out: centroid
00189                                    double& area);      // out: polygon area
00190 
00191 #ifdef NMWR_INCLUDE_TEMPLATE_DEFS
00192 #include "Geometry/algebraic-primitives.C"
00193 #endif
00194 
00195 #endif

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

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