00001 #ifndef NMWR_GB_POINT_H
00002 #define NMWR_GB_POINT_H
00003
00004 #include "Config/compiler-config.h"
00005
00006 #include <iostream.h>
00007 #include <stdlib.h>
00008
00009
00010 #include "Utility/pre-post-conditions.h"
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 class point
00023 {
00024 protected:
00025 int n;
00026 double* x;
00027
00028
00029
00030
00031 public:
00032
00033
00034 enum { no_init = 0, zero_init = 1};
00035 point() : n(0) { x = 0;}
00036
00037 point(int n1, int init)
00038 : n(n1) {x= new double[n]; if(init == zero_init) for(int i=0;i<=n-1;i++) x[i]=0.0;}
00039 explicit point(int n1) : n(n1), x(new double[n]) {}
00040 explicit point(const double x1);
00041 point(const double x, const double y);
00042 point(const double x, const double y, const double z);
00043 point(const double a[], int nn);
00044 point(const point& v);
00045 ~point() {if (n > 0) delete [] x;}
00046
00047 int dim() const { return n;}
00048
00049
00050
00051 point& operator = ( const point& v );
00052 point& operator += ( const point& v );
00053 point& operator -= ( const point& v );
00054 point& operator *= ( const double d );
00055 point& operator /= ( const double d );
00056 double& operator [] ( int i);
00057 const double& operator [] ( int i) const;
00058
00059
00060
00061 double length() const;
00062 double length2() const;
00063 point normalize() const;
00064
00065 friend point combine(const point& a, const point& b);
00066
00067 friend point operator - (const point& a);
00068 friend point operator + (const point& a, const point& b);
00069 friend point operator - (const point& a, const point& b);
00070 friend point operator * (const point& a, const double d);
00071 friend point operator * (const double d, const point& a);
00072 friend double operator * (const point& a, const point& b);
00073 friend point operator / (const point& a, const double d);
00074 friend ostream& operator << (ostream& s, const point& v);
00075 friend istream& operator >> (istream& s, point& v);
00076 friend void swap(point& a, point& b);
00077 };
00078
00079
00080 inline double& point::operator [] ( int i) {
00081 REQUIRE((i >= 1 && i <= n),
00082 "point [] operator: illegal access; index = " << i << '\n',1);
00083 return x[--i];
00084 }
00085
00086 inline const double& point::operator [] ( int i) const {
00087 REQUIRE((i >= 1 && i <= n),
00088 "point [] operator: illegal access; index = " << i << '\n',1);
00089 return x[i-1];
00090 }
00091
00092
00093 inline bool IsNullvector(const point& p)
00094 {
00095 for(int i=1;i<= p.dim(); i++)
00096 if(p[i] != 0.0)
00097 return false;
00098 return true;
00099 }
00100
00101
00102
00103 inline point unitvector(int dim, int i)
00104 {
00105 point p(dim,point::zero_init);
00106 p[i] = 1.0;
00107 return p;
00108 }
00109
00110
00111 inline point origin(int dim) { return point(dim,point::zero_init);}
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 #include "Geometry/point-traits.h"
00124
00125 template<>
00126 struct point_traits<point>
00127 : public point_traits_base<point>
00128 {
00129 typedef point Ptype;
00130 typedef double component_type;
00131 typedef variable_dimension_tag dimension_tag;
00132
00133
00134 static unsigned Dim (const Ptype& p) { return p.dim();}
00135 static int LowerIndex(const Ptype&) {return 1;}
00136 static int UpperIndex(const Ptype& p) {return Dim(p);}
00137 static void ConstructWithDim(int dim, Ptype& p)
00138 { p = Ptype(dim,Ptype::no_init);}
00139 static Ptype Origin(unsigned d) { return Ptype((int)d,Ptype::zero_init);}
00140
00141 static component_type x(const Ptype& p) { return p[1];}
00142 static component_type y(const Ptype& p) { return (Dim(p) > 1 ? p[2] : 0.0);}
00143 static component_type z(const Ptype& p) { return (Dim(p) > 2 ? p[3] : 0.0);}
00144
00145
00146 static component_type& x(Ptype& p) { return p[1];}
00147 static component_type& y(Ptype& p) { return p[2];}
00148 static component_type& z(Ptype& p) { return p[3];}
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160 };
00161
00162 #include "Geometry/algebraic-primitives.h"
00163
00164 struct dimension_dependent_primitives<point>
00165 : public basic_algebraic_primitives<point>
00166 {
00167 typedef dimension_dependent_primitives_2d<point> prim2d;
00168 typedef dimension_dependent_primitives_3d<point> prim3d;
00169
00170 static double det2(const point& p1, const point& p2) {
00171 REQUIRE((Dim(p1) == 2 && Dim(p2) == 2),
00172 "det2 called with dim(p,q) = " << Dim(p1) << "," << Dim(p2) << "!",1);
00173 return prim2d::det2(p1,p2);
00174 }
00175 static double det3(const point& p1, const point& p2, const point& p3) {
00176 REQUIRE((Dim(p1) == 3 && Dim(p2) == 3 && Dim(p3) == 3),
00177 "det3 called with dim(p,q,r) = "
00178 << Dim(p1) << "," << Dim(p2) << "," << Dim(p3) << "!",1);
00179 return prim3d::det3(p1,p2,p3);
00180 }
00181
00182 static double signed_triangle_area(const point& p1, const point& p2, const point& p3) {
00183 if(Dim(p1) == 2)
00184 return prim2d::signed_triangle_area(p1,p2,p3);
00185 else {
00186 ENSURE(false, "signed_triangle_area: not defined for dim > 2!",1);
00187 return 0.0;
00188 }
00189 }
00190
00191 static double triangle_area(const point& p1, const point& p2, const point& p3) {
00192 if (Dim(p1) == 2)
00193 return prim2d::triangle_area(p1,p2,p3);
00194 else if (Dim(p1) == 3)
00195 return prim3d::triangle_area(p1,p2,p3);
00196 else {
00197 ENSURE(false, "triangle_area: not implemented for dim > 3!",1);
00198 return 0.0;
00199 }
00200 }
00201
00202 static point vectorproduct(const point& p1, const point& p2) {
00203 REQUIRE((Dim(p1) == 3 && Dim(p2) == 3),
00204 "vectorproduct: called with dim(p,q) = "
00205 << Dim(p1) << "," << Dim(p2) << "!",1);
00206 return prim3d::vectorproduct(p1,p2);
00207 }
00208
00209 static point normal_with_same_length(const point& p) {
00210 REQUIRE((Dim(p) == 2),"normal: called with dim(p) = " << Dim(p) <<"!",1);
00211 return prim2d::normal_with_same_length(p);
00212 }
00213
00214 static point normed_normal(const point& p) {
00215 REQUIRE((Dim(p) == 2),"normal: called with dim(p) = " << Dim(p) <<"!",1);
00216 return prim2d::normed_normal(p);
00217 }
00218
00219 };
00220
00221
00222
00223
00224 #endif