00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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
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
00129
00130
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
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
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
00168
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
00180
00181
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
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
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
00206
00207
00208
00210
00216 friend Point<dim> Midpoint<dim>(const Point& p1, const Point& p2, CoordType dist);
00217
00218
00219
00221 Point (CoordType x, CoordType y);
00223 Point (CoordType x, CoordType y, CoordType z);
00224
00225
00226
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 }
00263
00264 #include <wfmath/point_funcs.h>
00265
00266 #endif // WFMATH_POINT_H