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
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
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, CoordType epsilon = numeric_constants<CoordType>::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
00135
00136
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
00150
00151 size_t numCorners() const {return 1;}
00152 Point<dim> getCorner(size_t) 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, size_t)
00157 {return operator=(p);}
00158 Point moveCenterTo(const Point& p) {return operator=(p);}
00159
00160 Point& rotateCorner(const RotMatrix<dim>&, size_t)
00161 {return *this;}
00162 Point& rotateCenter(const RotMatrix<dim>&) {return *this;}
00163 Point& rotatePoint(const RotMatrix<dim>& m, const Point& p) {return rotate(m, p);}
00164
00165
00166 Point& rotate(const Quaternion& q, const Point& p);
00167 Point& rotateCorner(const Quaternion&, size_t)
00168 { return *this;}
00169 Point& rotateCenter(const Quaternion&) {return *this;}
00170 Point& rotatePoint(const Quaternion& q, const Point& p);
00171
00172
00173
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
00185
00186
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
00195 Point toParentCoords(const Point& origin, const Quaternion& rotation) const;
00196 Point toLocalCoords(const Point& origin, const Quaternion& rotation) const;
00197
00198
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
00209
00210
00211
00213
00219 friend Point<dim> Midpoint<dim>(const Point& p1, const Point& p2, CoordType dist);
00220
00221
00222
00224 Point (CoordType x, CoordType y);
00226 Point (CoordType x, CoordType y, CoordType z);
00227
00228
00229
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;
00242 CoordType& z();
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 template<>
00266 inline CoordType Point<3>::z() const
00267 {
00268 return m_elem[2];
00269 }
00270
00271 template<>
00272 inline CoordType& Point<3>::z()
00273 {
00274 return m_elem[2];
00275 }
00276
00277 template<int dim>
00278 inline Point<dim> operator+(const Point<dim>& c, const Vector<dim>& v)
00279 {
00280 Point<dim> out(c);
00281
00282 out += v;
00283
00284 return out;
00285 }
00286
00287 template<int dim>
00288 inline Point<dim> operator+(const Vector<dim>& v, const Point<dim>& c)
00289 {
00290 Point<dim> out(c);
00291
00292 out += v;
00293
00294 return out;
00295 }
00296
00297 template<int dim>
00298 inline Point<dim> operator-(const Point<dim>& c, const Vector<dim>& v)
00299 {
00300 Point<dim> out(c);
00301
00302 out -= v;
00303
00304 return out;
00305 }
00306
00307 template<>
00308 inline Point<2>::Point(CoordType x, CoordType y) : m_valid(true)
00309 {
00310 m_elem[0] = x;
00311 m_elem[1] = y;
00312 }
00313
00314 template<>
00315 inline Point<3>::Point(CoordType x, CoordType y, CoordType z) : m_valid(true)
00316 {
00317 m_elem[0] = x;
00318 m_elem[1] = y;
00319 m_elem[2] = z;
00320 }
00321
00322 }
00323
00324 #endif // WFMATH_POINT_H