Common/Geom/Points.h

Go to the documentation of this file.
00001 //-------------------------------------------------------------------
00004 //  Copyright (c) 2004 Evan Sherbrooke and Michael Lauer
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License, or (at your option) any later version.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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 /*version*/)
00045    {
00046       ar & boost::serialization::make_nvp ("coord", m_coord);
00047    }
00048 public:
00050    enum { Dim = n };
00051    typedef double Coord;
00052 
00053    // default copy ctor, dtor, op= all ok
00055    PointNd() { makeZero(); }
00056    // These ctors all complain if called with the wrong n
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    // I'm leery of these, but they're useful for bezier stuff
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 /*version*/)
00102    {
00103       ar & boost::serialization::make_nvp ("coord", m_coord);
00104    }
00105 public:
00107    enum { Dim = n };
00108    typedef double Coord;
00109 
00110    // default copy ctor, dtor, op= all ok
00112    VecNd() { makeZero(); }
00113    // These ctors all complain if called with the wrong n
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 // Kinda yucky
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 // Homogeneous conversions
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 // Specializations for efficiency
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

Generated on Tue Jan 29 21:37:56 2008 for VoluMill Universal Client by  doxygen 1.4.6