00001 #ifndef NMWR_GB_ALGEBRAIC_PRIMITIVES
00002 #define NMWR_GB_ALGEBRAIC_PRIMITIVES
00003
00004
00005
00006
00007
00008 #include <math.h>
00009 #include "Utility/pre-post-conditions.h"
00010 #include "Geometry/point-traits.h"
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
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;
00048
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
00102
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
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
00178
00179
00180
00181
00182
00183
00184
00185
00186 template<class PIt, class Q>
00187 void get_polygon2d_center_and_area(PIt begin, PIt end,
00188 Q& center,
00189 double& area);
00190
00191 #ifdef NMWR_INCLUDE_TEMPLATE_DEFS
00192 #include "Geometry/algebraic-primitives.C"
00193 #endif
00194
00195 #endif