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