WFMath 0.3.11
|
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