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/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
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
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>
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 for (int i = 0; i < dim; ++i) {
00108 m_elem[i] = vector.elements()[i];
00109 }
00110 m_valid = true;
00111 }
00112
00116 static const Point<dim>& ZERO()
00117 {
00118 static ZeroPrimitive<Point<dim> > zeroPoint(dim);
00119 return zeroPoint.getShape();
00120 }
00121
00122 friend std::ostream& operator<< <dim>(std::ostream& os, const Point& p);
00123 friend std::istream& operator>> <dim>(std::istream& is, Point& p);
00124
00126 AtlasOutType toAtlas() const;
00128 void fromAtlas(const AtlasInType& a);
00129
00130 Point& operator= (const Point& rhs);
00131
00132 bool isEqualTo(const Point &p, double epsilon = WFMATH_EPSILON) const;
00133 bool operator== (const Point& rhs) const {return isEqualTo(rhs);}
00134 bool operator!= (const Point& rhs) const {return !isEqualTo(rhs);}
00135
00136 bool isValid() const {return m_valid;}
00138 void setValid(bool valid = true) {m_valid = valid;}
00139
00141 Point& setToOrigin();
00142
00143
00144
00145
00146 friend Vector<dim> operator-<dim>(const Point& c1, const Point& c2);
00147 friend Point operator+<dim>(const Point& c, const Vector<dim>& v);
00148 friend Point operator-<dim>(const Point& c, const Vector<dim>& v);
00149 friend Point operator+<dim>(const Vector<dim>& v, const Point& c);
00150
00151 friend Point& operator+=<dim>(Point& p, const Vector<dim>& rhs);
00152 friend Point& operator-=<dim>(Point& p, const Vector<dim>& rhs);
00153
00155 Point& rotate(const RotMatrix<dim>& m, const Point& p)
00156 {return (*this = p + Prod(*this - p, m));}
00157
00158
00159
00160 int numCorners() const {return 1;}
00161 Point<dim> getCorner(int i) const { return *this;}
00162 Point<dim> getCenter() const {return *this;}
00163
00164 Point shift(const Vector<dim>& v) {return *this += v;}
00165 Point moveCornerTo(const Point& p, int corner)
00166 {return operator=(p);}
00167 Point moveCenterTo(const Point& p) {return operator=(p);}
00168
00169 Point& rotateCorner(const RotMatrix<dim>& m, int corner)
00170 {return *this;}
00171 Point& rotateCenter(const RotMatrix<dim>& m) {return *this;}
00172 Point& rotatePoint(const RotMatrix<dim>& m, const Point& p) {return rotate(m, p);}
00173
00174
00175 Point<3>& rotate(const Quaternion& q, const Point<3>& p);
00176 Point& rotateCorner(const Quaternion& q, int corner)
00177 { return *this;}
00178 Point& rotateCenter(const Quaternion& q) {return *this;}
00179 Point<3>& rotatePoint(const Quaternion& q, const Point<3>& p);
00180
00181
00182
00183 AxisBox<dim> boundingBox() const;
00184 Ball<dim> boundingSphere() const;
00185 Ball<dim> boundingSphereSloppy() const;
00186
00187 Point toParentCoords(const Point& origin,
00188 const RotMatrix<dim>& rotation = RotMatrix<dim>().identity()) const
00189 {return origin + (*this - Point().setToOrigin()) * rotation;}
00190 Point toParentCoords(const AxisBox<dim>& coords) const;
00191 Point toParentCoords(const RotBox<dim>& coords) const;
00192
00193
00194
00195
00196
00197 Point toLocalCoords(const Point& origin,
00198 const RotMatrix<dim>& rotation = RotMatrix<dim>().identity()) const
00199 {return Point().setToOrigin() + rotation * (*this - origin);}
00200 Point toLocalCoords(const AxisBox<dim>& coords) const;
00201 Point toLocalCoords(const RotBox<dim>& coords) const;
00202
00203
00204 Point toParentCoords(const Point& origin, const Quaternion& rotation) const;
00205 Point toLocalCoords(const Point& origin, const Quaternion& rotation) const;
00206
00207
00208
00210 CoordType operator[](const int i) const {return m_elem[i];}
00212 CoordType& operator[](const int i) {return m_elem[i];}
00213
00215 friend CoordType SquaredDistance<dim>(const Point& p1, const Point& p2);
00216
00217
00218
00219
00220
00222
00228 friend Point<dim> Midpoint<dim>(const Point& p1, const Point& p2, CoordType dist);
00229
00230
00231
00233 Point (CoordType x, CoordType y);
00235 Point (CoordType x, CoordType y, CoordType z);
00236
00237
00238
00239
00241 CoordType x() const {return m_elem[0];}
00243 CoordType& x() {return m_elem[0];}
00245 CoordType y() const {return m_elem[1];}
00247 CoordType& y() {return m_elem[1];}
00249 CoordType z() const {return m_elem[2];}
00251 CoordType& z() {return m_elem[2];}
00252
00254 Point<2>& polar(CoordType r, CoordType theta);
00256 void asPolar(CoordType& r, CoordType& theta) const;
00257
00259 Point<3>& polar(CoordType r, CoordType theta, CoordType z);
00261 void asPolar(CoordType& r, CoordType& theta, CoordType& z) const;
00263 Point<3>& spherical(CoordType r, CoordType theta, CoordType phi);
00265 void asSpherical(CoordType& r, CoordType& theta, CoordType& phi) const;
00266
00267 const CoordType* elements() const {return m_elem;}
00268
00269 private:
00270 CoordType m_elem[dim];
00271 bool m_valid;
00272 };
00273
00274 }
00275
00276 #endif // WFMATH_POINT_H