point.h

00001 // point.h (point class copied from libCoal, subsequently modified)
00002 //
00003 //  The WorldForge Project
00004 //  Copyright (C) 2000, 2001, 2002  The WorldForge Project
00005 //
00006 //  This program is free software; you can redistribute it and/or modify
00007 //  it under the terms of the GNU General Public License as published by
00008 //  the Free Software Foundation; either version 2 of the License, or
00009 //  (at your option) any later version.
00010 //
00011 //  This program 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
00014 //  GNU General Public License for more details.
00015 //
00016 //  You should have received a copy of the GNU General Public License
00017 //  along with this program; if not, write to the Free Software
00018 //  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019 //
00020 //  For information about WorldForge and its authors, please contact
00021 //  the Worldforge Web Site at http://www.worldforge.org.
00022 //
00023 
00024 // Author: Ron Steinke
00025 
00026 #ifndef WFMATH_POINT_H
00027 #define WFMATH_POINT_H
00028 
00029 #include <wfmath/const.h>
00030 #include <wfmath/vector.h>
00031 #include <wfmath/rotmatrix.h>
00032 #include <wfmath/quaternion.h>
00033 
00034 namespace WFMath {
00035 
00036 template<const int dim> class Point;
00037 template<const int dim> class AxisBox;
00038 template<const int dim> class Ball;
00039 template<const int dim> class RotBox;
00040 
00041 template<const int dim>
00042 Point<dim>& operator+=(Point<dim>& p, const Vector<dim>& v);
00043 template<const int dim>
00044 Point<dim>& operator-=(Point<dim>& p, const Vector<dim>& v);
00045 
00046 template<const int dim>
00047 Vector<dim> operator-(const Point<dim>& c1, const Point<dim>& c2);
00048 template<const int dim>
00049 Point<dim> operator+(const Point<dim>& c, const Vector<dim>& v);
00050 template<const int dim>
00051 Point<dim> operator+(const Vector<dim>& v, const Point<dim>& c);
00052 template<const int dim>
00053 Point<dim> operator-(const Point<dim>& c, const Vector<dim>& v);
00054 
00055 template<const int dim>
00056 CoordType SquaredDistance(const Point<dim>& p1, const Point<dim>& p2);
00057 template<const int dim>
00058 CoordType Distance(const Point<dim>& p1, const Point<dim>& p2)
00059         {return sqrt(SquaredDistance(p1, p2));}
00060 template<const int dim>
00061 CoordType SloppyDistance(const Point<dim>& p1, const Point<dim>& p2)
00062         {return (p1 - p2).sloppyMag();}
00063 
00064 #ifndef WFMATH_NO_TEMPLATES_AS_TEMPLATE_PARAMETERS
00066 template<const int dim, template<class, class> class container>
00067 Point<dim> Barycenter(const container<Point<dim>, std::allocator<Point<dim> > >& c);
00069 
00075 template<const int dim, template<class, class> class container,
00076                         template<class, class> class container2>
00077 Point<dim> Barycenter(const container<Point<dim>, std::allocator<Point<dim> > >& c,
00078                       const container2<CoordType, std::allocator<CoordType> >& weights);
00079 #endif
00080 
00081 // This is used a couple of places in the library
00082 template<const int dim>
00083 Point<dim> Midpoint(const Point<dim>& p1, const Point<dim>& p2,
00084                     CoordType dist = 0.5);
00085 
00086 template<const int dim>
00087 std::ostream& operator<<(std::ostream& os, const Point<dim>& m);
00088 template<const int dim>
00089 std::istream& operator>>(std::istream& is, Point<dim>& m);
00090 
00092 
00096 template<const int dim>
00097 class Point
00098 {
00099  public:
00101   Point () : m_valid(false) {}
00103   Point (const Point& p);
00105   explicit Point (const AtlasInType& a) {fromAtlas(a);}
00106 
00107   friend std::ostream& operator<< <dim>(std::ostream& os, const Point& p);
00108   friend std::istream& operator>> <dim>(std::istream& is, Point& p);
00109 
00111   AtlasOutType toAtlas() const;
00113   void fromAtlas(const AtlasInType& a);
00114 
00115   Point& operator= (const Point& rhs);
00116 
00117   bool isEqualTo(const Point &p, double epsilon = WFMATH_EPSILON) const;
00118   bool operator== (const Point& rhs) const      {return isEqualTo(rhs);}
00119   bool operator!= (const Point& rhs) const      {return !isEqualTo(rhs);}
00120 
00121   bool isValid() const {return m_valid;}
00123   void setValid(bool valid = true) {m_valid = valid;}
00124 
00126   Point& setToOrigin();
00127 
00128   // Operators
00129 
00130   // Documented in vector.h
00131   friend Vector<dim> operator-<dim>(const Point& c1, const Point& c2);
00132   friend Point operator+<dim>(const Point& c, const Vector<dim>& v);
00133   friend Point operator-<dim>(const Point& c, const Vector<dim>& v);
00134   friend Point operator+<dim>(const Vector<dim>& v, const Point& c);
00135 
00136   friend Point& operator+=<dim>(Point& p, const Vector<dim>& rhs);
00137   friend Point& operator-=<dim>(Point& p, const Vector<dim>& rhs);
00138 
00140   Point& rotate(const RotMatrix<dim>& m, const Point& p)
00141         {return (*this = p + Prod(*this - p, m));}
00142 
00143   // Functions so that Point<> has the generic shape interface
00144 
00145   int numCorners() const {return 1;}
00146   Point<dim> getCorner(int i) const {assert(i == 0); return *this;}
00147   Point<dim> getCenter() const {return *this;}
00148 
00149   Point shift(const Vector<dim>& v) {return *this += v;}
00150   Point moveCornerTo(const Point& p, int corner)
00151         {assert(corner == 0); return operator=(p);}
00152   Point moveCenterTo(const Point& p) {return operator=(p);}
00153 
00154   Point& rotateCorner(const RotMatrix<dim>& m, int corner)
00155         {assert(corner == 0); return *this;}
00156   Point& rotateCenter(const RotMatrix<dim>& m) {return *this;}
00157   Point& rotatePoint(const RotMatrix<dim>& m, const Point& p) {return rotate(m, p);}
00158 
00159   // 3D rotation functions
00160   Point<3>& rotate(const Quaternion& q, const Point<3>& p)
00161         {return (*this = p + (*this - p).rotate(q));}
00162   Point<3>& rotateCorner(const Quaternion& q, int corner)
00163         {assert(corner == 0); return *this;}
00164   Point<3>& rotateCenter(const Quaternion& q) {return *this;}
00165   Point<3>& rotatePoint(const Quaternion& q, const Point<3>& p) {return rotate(q, p);}
00166 
00167   // The implementations of these lie in axisbox_funcs.h and
00168   // ball_funcs.h, to reduce include dependencies
00169   AxisBox<dim> boundingBox() const;
00170   Ball<dim> boundingSphere() const;
00171   Ball<dim> boundingSphereSloppy() const;
00172 
00173   Point toParentCoords(const Point& origin,
00174       const RotMatrix<dim>& rotation = RotMatrix<dim>().identity()) const
00175         {return origin + (*this - Point().setToOrigin()) * rotation;}
00176   Point toParentCoords(const AxisBox<dim>& coords) const;
00177   Point toParentCoords(const RotBox<dim>& coords) const;
00178 
00179   // toLocal is just like toParent, expect we reverse the order of
00180   // translation and rotation and use the opposite sense of the rotation
00181   // matrix
00182 
00183   Point toLocalCoords(const Point& origin,
00184       const RotMatrix<dim>& rotation = RotMatrix<dim>().identity()) const
00185         {return Point().setToOrigin() + rotation * (*this - origin);}
00186   Point toLocalCoords(const AxisBox<dim>& coords) const;
00187   Point toLocalCoords(const RotBox<dim>& coords) const;
00188 
00189   // 3D only
00190   Point<3> toParentCoords(const Point<3>& origin, const Quaternion& rotation) const
00191         {return origin + (*this - Point().setToOrigin()).rotate(rotation);}
00192   Point<3> toLocalCoords(const Point<3>& origin, const Quaternion& rotation) const
00193         {return Point().setToOrigin() + (*this - origin).rotate(rotation.inverse());}
00194 
00195   // Member access
00196 
00198   CoordType operator[](const int i) const {assert(i >= 0 && i < dim); return m_elem[i];}
00200   CoordType& operator[](const int i)      {assert(i >= 0 && i < dim); return m_elem[i];}
00201 
00203   friend CoordType SquaredDistance<dim>(const Point& p1, const Point& p2);
00204 
00205 // FIXME instatiation problem when declared as friend
00206 //  template<template<class> class container>
00207 //  friend Point Barycenter(const container<Point>& c);
00208 
00210 
00216   friend Point<dim> Midpoint<dim>(const Point& p1, const Point& p2, CoordType dist);
00217 
00218   // 2D/3D stuff
00219 
00221   Point (CoordType x, CoordType y); // 2D only
00223   Point (CoordType x, CoordType y, CoordType z); // 3D only
00224 
00225   // Label the first three components of the vector as (x,y,z) for
00226   // 2D/3D convienience
00227 
00229   CoordType x() const   {assert(dim > 0); return m_elem[0];}
00231   CoordType& x()        {assert(dim > 0); return m_elem[0];}
00233   CoordType y() const   {assert(dim > 1); return m_elem[1];}
00235   CoordType& y()        {assert(dim > 1); return m_elem[1];}
00237   CoordType z() const   {assert(dim > 2); return m_elem[2];}
00239   CoordType& z()        {assert(dim > 2); return m_elem[2];}
00240 
00242   Point<2>& polar(CoordType r, CoordType theta);
00244   void asPolar(CoordType& r, CoordType& theta) const;
00245 
00247   Point<3>& polar(CoordType r, CoordType theta, CoordType z);
00249   void asPolar(CoordType& r, CoordType& theta, CoordType& z) const;
00251   Point<3>& spherical(CoordType r, CoordType theta, CoordType phi);
00253   void asSpherical(CoordType& r, CoordType& theta, CoordType& phi) const;
00254 
00255   const CoordType* elements() const {return m_elem;}
00256 
00257  private:
00258   CoordType m_elem[dim];
00259   bool m_valid;
00260 };
00261 
00262 } // namespace WFMath
00263 
00264 #include <wfmath/point_funcs.h>
00265 
00266 #endif  // WFMATH_POINT_H

Generated on Wed Aug 22 01:55:42 2007 for WFMath by  doxygen 1.5.2