00001
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #pragma once
00022
00023 #ifndef VOLUMILL_POINTS_H
00024 #define VOLUMILL_POINTS_H
00025
00026
00027
00028 #include <cassert>
00029 #include <boost/static_assert.hpp>
00030
00031 namespace geom
00032 {
00033
00034 template <int n> class VecNd;
00035
00039 template <int n>
00040 class PointNd
00041 {
00042 friend class boost::serialization::access;
00043 template<class Archive>
00044 void serialize(Archive & ar, const unsigned int )
00045 {
00046 ar & boost::serialization::make_nvp ("coord", m_coord);
00047 }
00048 public:
00050 enum { Dim = n };
00051 typedef double Coord;
00052
00053
00055 PointNd() { makeZero(); }
00056
00058 inline PointNd(double a, double b);
00060 inline PointNd(double a, double b, double c);
00062 inline PointNd(double a, double b, double c, double d);
00064 inline explicit PointNd(const VecNd<n> &);
00065
00067 double operator[] (int ii) const { return m_coord[ii]; }
00069 double &operator[] (int ii) { return m_coord[ii]; }
00070
00072 inline PointNd<n> &operator+= (const VecNd<n> &);
00074 inline PointNd<n> &operator-= (const VecNd<n> &);
00075
00076
00078 inline PointNd<n> &operator+= (const PointNd<n> &);
00080 inline PointNd<n> &operator-= (const PointNd<n> &);
00082 inline PointNd<n> &operator*= (double);
00084 inline PointNd<n> &operator/= (double);
00085
00087 inline void makeZero()
00088 { for(int ii=0; ii<n; ii++) m_coord[ii] = 0; }
00089 private:
00090 Coord m_coord[n];
00091 };
00092
00096 template <int n>
00097 class VecNd
00098 {
00099 friend class boost::serialization::access;
00100 template<class Archive>
00101 void serialize(Archive & ar, const unsigned int )
00102 {
00103 ar & boost::serialization::make_nvp ("coord", m_coord);
00104 }
00105 public:
00107 enum { Dim = n };
00108 typedef double Coord;
00109
00110
00112 VecNd() { makeZero(); }
00113
00115 inline VecNd(double a, double b);
00117 inline VecNd(double a, double b, double c);
00119 inline VecNd(double a, double b, double c, double d);
00121 inline explicit VecNd(const PointNd<n> &);
00122
00124 double operator[] (int ii) const { return m_coord[ii]; }
00126 double &operator[] (int ii) { return m_coord[ii]; }
00127
00129 inline VecNd<n> &operator+= (const VecNd<n> &);
00131 inline VecNd<n> &operator-= (const VecNd<n> &);
00132
00134 inline VecNd<n> &operator*= (double);
00136 inline VecNd<n> &operator/= (double);
00137
00139 inline void makeZero()
00140 { for(int ii=0; ii<n; ii++) m_coord[ii] = 0; }
00141
00142 private:
00143 Coord m_coord[n];
00144 };
00145
00146 template <int n>
00147 PointNd<n>::PointNd(double a, double b)
00148 {
00149 BOOST_STATIC_ASSERT(n == 2);
00150 m_coord[0] = a;
00151 m_coord[1] = b;
00152 }
00153
00154 template <int n>
00155 PointNd<n>::PointNd(double a, double b, double c)
00156 {
00157 BOOST_STATIC_ASSERT(n == 3);
00158 m_coord[0] = a;
00159 m_coord[1] = b;
00160 m_coord[2] = c;
00161 }
00162
00163 template <int n>
00164 PointNd<n>::PointNd(double a, double b, double c, double d)
00165 {
00166 BOOST_STATIC_ASSERT(n == 4);
00167 m_coord[0] = a;
00168 m_coord[1] = b;
00169 m_coord[2] = c;
00170 m_coord[3] = d;
00171 }
00172
00173 template <int n>
00174 PointNd<n>::PointNd(const VecNd<n> &v)
00175 {
00176 for(int ii=0; ii<n; ii++)
00177 m_coord[ii] = v[ii];
00178 }
00179
00180 template <int n>
00181 VecNd<n>::VecNd(double a, double b)
00182 {
00183 BOOST_STATIC_ASSERT(n == 2);
00184 m_coord[0] = a;
00185 m_coord[1] = b;
00186 }
00187
00188 template <int n>
00189 VecNd<n>::VecNd(double a, double b, double c)
00190 {
00191 BOOST_STATIC_ASSERT(n == 3);
00192 m_coord[0] = a;
00193 m_coord[1] = b;
00194 m_coord[2] = c;
00195 }
00196
00197 template <int n>
00198 VecNd<n>::VecNd(double a, double b, double c, double d)
00199 {
00200 BOOST_STATIC_ASSERT(n == 4);
00201 m_coord[0] = a;
00202 m_coord[1] = b;
00203 m_coord[2] = c;
00204 m_coord[3] = d;
00205 }
00206
00207 template <int n>
00208 VecNd<n>::VecNd(const PointNd<n> &pt)
00209 {
00210 for(int ii=0; ii<n; ii++)
00211 m_coord[ii] = pt[ii];
00212 }
00213
00214 template <int n>
00215 PointNd<n> &PointNd<n>::operator+=(const VecNd<n> &vec)
00216 {
00217 for(int ii=0; ii<n; ii++)
00218 m_coord[ii] += vec[ii];
00219 return *this;
00220 }
00221
00222 template <int n>
00223 PointNd<n> &PointNd<n>::operator-=(const VecNd<n> &vec)
00224 {
00225 for(int ii=0; ii<n; ii++)
00226 m_coord[ii] -= vec[ii];
00227 return *this;
00228 }
00229
00230 template <int n>
00231 PointNd<n> &PointNd<n>::operator+=(const PointNd<n> &pt)
00232 {
00233 for(int ii=0; ii<n; ii++)
00234 m_coord[ii] += pt[ii];
00235 return *this;
00236 }
00237
00238 template <int n>
00239 PointNd<n> &PointNd<n>::operator-=(const PointNd<n> &pt)
00240 {
00241 for(int ii=0; ii<n; ii++)
00242 m_coord[ii] -= pt[ii];
00243 return *this;
00244 }
00245
00246 template <int n>
00247 PointNd<n> &PointNd<n>::operator*=(double scale)
00248 {
00249 for(int ii=0; ii<n; ii++)
00250 m_coord[ii] *= scale;
00251 return *this;
00252 }
00253
00254 template <int n>
00255 inline PointNd<n> &PointNd<n>::operator/= (double scale)
00256 {
00257 for(int ii=0; ii<n; ii++)
00258 m_coord[ii] /= scale;
00259 return *this;
00260 }
00261
00262 template <int n>
00263 VecNd<n> &VecNd<n>::operator+=(const VecNd<n> &vec)
00264 {
00265 for(int ii=0; ii<n; ii++)
00266 m_coord[ii] += vec[ii];
00267 return *this;
00268 }
00269
00270 template <int n>
00271 VecNd<n> &VecNd<n>::operator-=(const VecNd<n> &vec)
00272 {
00273 for(int ii=0; ii<n; ii++)
00274 m_coord[ii] -= vec[ii];
00275 return *this;
00276 }
00277
00278 template <int n>
00279 VecNd<n> &VecNd<n>::operator*=(double scale)
00280 {
00281 for(int ii=0; ii<n; ii++)
00282 m_coord[ii] *= scale;
00283 return *this;
00284 }
00285
00286 template <int n>
00287 inline VecNd<n> &VecNd<n>::operator/= (double scale)
00288 {
00289 for(int ii=0; ii<n; ii++)
00290 m_coord[ii] /= scale;
00291 return *this;
00292 }
00293
00294 template <int n>
00295 inline
00296 PointNd<n> operator+(const PointNd<n> &pt, const VecNd<n> &vec)
00297 {
00298 PointNd<n> ret(pt);
00299 return ret += vec;
00300 }
00301
00302 template <int n>
00303 inline
00304 PointNd<n> operator-(const PointNd<n> &pt, const VecNd<n> &vec)
00305 {
00306 PointNd<n> ret(pt);
00307 return ret -= vec;
00308 }
00309
00310 template <int n>
00311 inline
00312 PointNd<n> operator+(const PointNd<n> &pt, const PointNd<n> &pt1)
00313 {
00314 PointNd<n> ret(pt);
00315 return ret += pt1;
00316 }
00317
00318 template <int n>
00319 inline
00320 PointNd<n> operator*(const PointNd<n> &pt, double scale)
00321 {
00322 PointNd<n> ret(pt);
00323 ret *= scale;
00324 return ret;
00325 }
00326
00327 template <int n>
00328 inline
00329 PointNd<n> operator/(const PointNd<n> &pt, double scale)
00330 {
00331 PointNd<n> ret(pt);
00332 ret /= scale;
00333 return ret;
00334 }
00335
00336 template <int n>
00337 inline
00338 PointNd<n> operator*(double scale, const PointNd<n> &pt)
00339 {
00340 return pt * scale;
00341 }
00342
00343 template <int n>
00344 inline
00345 VecNd<n> operator+(const VecNd<n> &vec0, const VecNd<n> &vec)
00346 {
00347 VecNd<n> ret(vec0);
00348 return ret += vec;
00349 }
00350
00351 template <int n>
00352 inline
00353 VecNd<n> operator-(const VecNd<n> &vec0, const VecNd<n> &vec)
00354 {
00355 VecNd<n> ret(vec0);
00356 return ret -= vec;
00357 }
00358
00359 template <int n>
00360 inline
00361 VecNd<n> operator*(const VecNd<n> &v, double scale)
00362 {
00363 VecNd<n> ret(v);
00364 ret *= scale;
00365 return ret;
00366 }
00367
00368 template <int n>
00369 inline
00370 VecNd<n> operator*(double scale, const VecNd<n> &v)
00371 {
00372 VecNd<n> ret(v);
00373 ret *= scale;
00374 return ret;
00375 }
00376
00377 template <int n>
00378 inline
00379 PointNd<n> operator-(const PointNd<n> &pt0, const PointNd<n> &pt1)
00380 {
00381 PointNd<n> ret;
00382 for(int ii=0; ii<n; ii++)
00383 ret[ii] = pt0[ii]-pt1[ii];
00384 return ret;
00385 }
00386
00387 template<int n>
00388 inline
00389 PointNd<n> operator-(const PointNd<n>& pt)
00390 {
00391 PointNd<n> ret;
00392 for (int ii=0; ii<n; ++ii)
00393 ret[ii] = -pt[ii];
00394 return ret;
00395 }
00396
00398 template <int n>
00399 inline
00400 double operator*(const VecNd<n> &vec0, const VecNd<n> &vec1)
00401 {
00402 double ff = 0;
00403 for(int ii=0; ii<n; ii++)
00404 ff += vec0[ii] * vec1[ii];
00405 return ff;
00406 }
00407
00409 template <int n>
00410 inline
00411 double operator*(const PointNd<n> &pt0, const PointNd<n> &pt1)
00412 {
00413 double ff = 0;
00414 for(int ii=0; ii<n; ii++)
00415 ff += pt0[ii] * pt1[ii];
00416 return ff;
00417 }
00418
00420 template <int n>
00421 PointNd<n> linComb(double d0,
00422 const PointNd<n> &pt0,
00423 double d1,
00424 const PointNd<n> &pt1)
00425 {
00426 PointNd<n> ret;
00427 for(int ii=0; ii<n; ii++)
00428 ret[ii] = d0*pt0[ii] + d1*pt1[ii];
00429 return ret;
00430 }
00431
00433 template <int n>
00434 VecNd<n> linComb(double d0,
00435 const VecNd<n> &pt0,
00436 double d1,
00437 const VecNd<n> &pt1)
00438 {
00439 VecNd<n> ret;
00440 for(int ii=0; ii<n; ii++)
00441 ret[ii] = d0*pt0[ii] + d1*pt1[ii];
00442 return ret;
00443 }
00444
00445
00447 template <int n>
00448 bool operator==(const PointNd<n> &pt0, const PointNd<n> &pt1)
00449 {
00450 for(int ii=0; ii<n; ii++)
00451 {
00452 if(pt0[ii] != pt1[ii])
00453 return false;
00454 }
00455 return true;
00456 }
00457
00459 template <int n>
00460 bool operator!=(const PointNd<n> &pt0, const PointNd<n> &pt1)
00461 {
00462 return !(pt0 == pt1);
00463 }
00464
00467 template <int n>
00468 bool operator< (const PointNd<n> &pt0, const PointNd<n> &pt1)
00469 {
00470 for (int ii=0; ii < n; ++ii)
00471 {
00472 if (pt0[ii] < pt1[ii])
00473 return true;
00474 else if (pt1[ii] < pt0[ii])
00475 return false;
00476 }
00477 return false;
00478 }
00479
00481 typedef PointNd<2> Point2d;
00483 typedef VecNd<2> Vec2d;
00485 typedef PointNd<3> Point3d;
00487 typedef VecNd<3> Vec3d;
00489 typedef PointNd<4> Point4d;
00491 typedef VecNd<4> Vec4d;
00492
00493
00497 template <int n>
00498 inline
00499 PointNd<n-1> projectHomogeneous(const PointNd<n> &pt)
00500 {
00501 PointNd<n-1> ret;
00502 double denom = 1.0/pt[n-1];
00503 for(int ii=0; ii<n-1; ii++)
00504 ret[ii] = pt[ii]*denom;
00505 return ret;
00506 }
00507
00512 template <int n>
00513 inline
00514 PointNd<n+1> makeHomogeneous(const PointNd<n> &pt, double weight = 1.0)
00515 {
00516 PointNd<n+1> ret;
00517 for(int ii=0; ii<n; ii++)
00518 ret[ii] = pt[ii] * weight;
00519 ret[n] = weight;
00520 return ret;
00521 }
00522
00524
00525
00526
00527 inline
00528 PointNd<3> operator+(const PointNd<3> &pt, const VecNd<3> &vec)
00529 {
00530 return PointNd<3> (pt[0] + vec[0], pt[1] + vec[1], pt[2] + vec[2]);
00531 }
00532
00533 inline
00534 PointNd<3> operator+(const PointNd<3> &pt, const PointNd<3> &pt1)
00535 {
00536 return PointNd<3> (pt[0] + pt1[0], pt[1] + pt1[1], pt[2] + pt1[2]);
00537 }
00538
00539 inline
00540 PointNd<3> operator-(const PointNd<3> &pt, const VecNd<3> &vec)
00541 {
00542 return PointNd<3> (pt[0] - vec[0], pt[1] - vec[1], pt[2] - vec[2]);
00543 }
00544
00545 inline
00546 PointNd<3> operator*(const PointNd<3> &pt, double scale)
00547 {
00548 return PointNd<3> (pt[0] * scale, pt[1] * scale, pt[2] * scale);
00549 }
00550
00551 inline
00552 PointNd<3> operator/(const PointNd<3> &pt, double scale)
00553 {
00554 return PointNd<3> (pt[0] / scale, pt[1] / scale, pt[2] / scale);
00555 }
00556
00557 }
00558 #endif