WFMath 0.3.11
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/zero.h>
00031 
00032 #include <memory>
00033 #include <iosfwd>
00034 
00035 namespace WFMath {
00036 
00037 template<const int dim>
00038 Point<dim>& operator+=(Point<dim>& p, const Vector<dim>& v);
00039 template<const int dim>
00040 Point<dim>& operator-=(Point<dim>& p, const Vector<dim>& v);
00041 
00042 template<const int dim>
00043 Vector<dim> operator-(const Point<dim>& c1, const Point<dim>& c2);
00044 template<const int dim>
00045 Point<dim> operator+(const Point<dim>& c, const Vector<dim>& v);
00046 template<const int dim>
00047 Point<dim> operator+(const Vector<dim>& v, const Point<dim>& c);
00048 template<const int dim>
00049 Point<dim> operator-(const Point<dim>& c, const Vector<dim>& v);
00050 
00051 template<const int dim>
00052 CoordType SquaredDistance(const Point<dim>& p1, const Point<dim>& p2);
00053 template<const int dim>
00054 CoordType Distance(const Point<dim>& p1, const Point<dim>& p2)
00055   {return sqrt(SquaredDistance(p1, p2));}
00056 template<const int dim>
00057 CoordType SloppyDistance(const Point<dim>& p1, const Point<dim>& p2)
00058   {return (p1 - p2).sloppyMag();}
00059 
00060 #ifndef WFMATH_NO_TEMPLATES_AS_TEMPLATE_PARAMETERS
00061 
00062 template<const int dim, template<class, class> class container>
00063 Point<dim> Barycenter(const container<Point<dim>, std::allocator<Point<dim> > >& c);
00065 
00071 template<const int dim, template<class, class> class container,
00072       template<class, class> class container2>
00073 Point<dim> Barycenter(const container<Point<dim>, std::allocator<Point<dim> > >& c,
00074           const container2<CoordType, std::allocator<CoordType> >& weights);
00075 #endif
00076 
00077 // This is used a couple of places in the library
00078 template<const int dim>
00079 Point<dim> Midpoint(const Point<dim>& p1, const Point<dim>& p2,
00080         CoordType dist = 0.5);
00081 
00082 template<const int dim>
00083 std::ostream& operator<<(std::ostream& os, const Point<dim>& m);
00084 template<const int dim>
00085 std::istream& operator>>(std::istream& is, Point<dim>& m);
00086 
00087 
00088 
00090 
00094 template<const int dim = 3>
00095 class Point
00096 {
00097  friend class ZeroPrimitive<Point<dim> >;
00098  public:
00100   Point () : m_valid(false) {}
00102   Point (const Point& p);
00104   explicit Point (const AtlasInType& a);
00106   explicit Point(const Vector<dim>& vector);
00107 
00111   static const Point<dim>& ZERO()
00112   {
00113     static ZeroPrimitive<Point<dim> > zeroPoint(dim);
00114     return zeroPoint.getShape();
00115   }
00116 
00117   friend std::ostream& operator<< <dim>(std::ostream& os, const Point& p);
00118   friend std::istream& operator>> <dim>(std::istream& is, Point& p);
00119 
00121   AtlasOutType toAtlas() const;
00123   void fromAtlas(const AtlasInType& a);
00124 
00125   Point& operator= (const Point& rhs);
00126 
00127   bool isEqualTo(const Point &p, double epsilon = WFMATH_EPSILON) const;
00128   bool operator== (const Point& rhs) const      {return isEqualTo(rhs);}
00129   bool operator!= (const Point& rhs) const      {return !isEqualTo(rhs);}
00130 
00131   bool isValid() const {return m_valid;}
00133   void setValid(bool valid = true) {m_valid = valid;}
00134 
00136   Point& setToOrigin();
00137 
00138   // Operators
00139 
00140   // Documented in vector.h
00141   friend Vector<dim> operator-<dim>(const Point& c1, const Point& c2);
00142   friend Point operator+<dim>(const Point& c, const Vector<dim>& v);
00143   friend Point operator-<dim>(const Point& c, const Vector<dim>& v);
00144   friend Point operator+<dim>(const Vector<dim>& v, const Point& c);
00145 
00146   friend Point& operator+=<dim>(Point& p, const Vector<dim>& rhs);
00147   friend Point& operator-=<dim>(Point& p, const Vector<dim>& rhs);
00148 
00150   Point& rotate(const RotMatrix<dim>& m, const Point& p)
00151   {return (*this = p + Prod(*this - p, m));}
00152 
00153   // Functions so that Point<> has the generic shape interface
00154 
00155   int numCorners() const {return 1;}
00156   Point<dim> getCorner(int i) const { return *this;}
00157   Point<dim> getCenter() const {return *this;}
00158 
00159   Point shift(const Vector<dim>& v) {return *this += v;}
00160   Point moveCornerTo(const Point& p, int corner)
00161   {return operator=(p);}
00162   Point moveCenterTo(const Point& p) {return operator=(p);}
00163 
00164   Point& rotateCorner(const RotMatrix<dim>& m, int corner)
00165   {return *this;}
00166   Point& rotateCenter(const RotMatrix<dim>& m) {return *this;}
00167   Point& rotatePoint(const RotMatrix<dim>& m, const Point& p) {return rotate(m, p);}
00168 
00169   // 3D rotation functions
00170   Point& rotate(const Quaternion& q, const Point& p);
00171   Point& rotateCorner(const Quaternion& q, int corner)
00172   { return *this;}
00173   Point& rotateCenter(const Quaternion& q) {return *this;}
00174   Point& rotatePoint(const Quaternion& q, const Point& p);
00175 
00176   // The implementations of these lie in axisbox_funcs.h and
00177   // ball_funcs.h, to reduce include dependencies
00178   AxisBox<dim> boundingBox() const;
00179   Ball<dim> boundingSphere() const;
00180   Ball<dim> boundingSphereSloppy() const;
00181 
00182   Point toParentCoords(const Point& origin,
00183       const RotMatrix<dim>& rotation = RotMatrix<dim>().identity()) const
00184   {return origin + (*this - Point().setToOrigin()) * rotation;}
00185   Point toParentCoords(const AxisBox<dim>& coords) const;
00186   Point toParentCoords(const RotBox<dim>& coords) const;
00187 
00188   // toLocal is just like toParent, expect we reverse the order of
00189   // translation and rotation and use the opposite sense of the rotation
00190   // matrix
00191 
00192   Point toLocalCoords(const Point& origin,
00193       const RotMatrix<dim>& rotation = RotMatrix<dim>().identity()) const
00194   {return Point().setToOrigin() + rotation * (*this - origin);}
00195   Point toLocalCoords(const AxisBox<dim>& coords) const;
00196   Point toLocalCoords(const RotBox<dim>& coords) const;
00197 
00198   // 3D only
00199   Point toParentCoords(const Point& origin, const Quaternion& rotation) const;
00200   Point toLocalCoords(const Point& origin, const Quaternion& rotation) const;
00201 
00202   // Member access
00203 
00205   CoordType operator[](const int i) const {return m_elem[i];}
00207   CoordType& operator[](const int i)      {return m_elem[i];}
00208 
00210   friend CoordType SquaredDistance<dim>(const Point& p1, const Point& p2);
00211 
00212 // FIXME instatiation problem when declared as friend
00213 //  template<template<class> class container>
00214 //  friend Point Barycenter(const container<Point>& c);
00215 
00217 
00223   friend Point<dim> Midpoint<dim>(const Point& p1, const Point& p2, CoordType dist);
00224 
00225   // 2D/3D stuff
00226 
00228   Point (CoordType x, CoordType y); // 2D only
00230   Point (CoordType x, CoordType y, CoordType z); // 3D only
00231 
00232   // Label the first three components of the vector as (x,y,z) for
00233   // 2D/3D convienience
00234 
00236   CoordType x() const   {return m_elem[0];}
00238   CoordType& x()        {return m_elem[0];}
00240   CoordType y() const   {return m_elem[1];}
00242   CoordType& y()        {return m_elem[1];}
00244   CoordType z() const   {return m_elem[2];}
00246   CoordType& z()        {return m_elem[2];}
00247 
00249   Point& polar(CoordType r, CoordType theta);
00251   void asPolar(CoordType& r, CoordType& theta) const;
00252 
00254   Point& polar(CoordType r, CoordType theta, CoordType z);
00256   void asPolar(CoordType& r, CoordType& theta, CoordType& z) const;
00258   Point& spherical(CoordType r, CoordType theta, CoordType phi);
00260   void asSpherical(CoordType& r, CoordType& theta, CoordType& phi) const;
00261 
00262   const CoordType* elements() const {return m_elem;}
00263 
00264  private:
00265   CoordType m_elem[dim];
00266   bool m_valid;
00267 };
00268 
00269 } // namespace WFMath
00270 
00271 #endif  // WFMATH_POINT_H