WFMath  1.0.1
point.h
1 // point.h (point class copied from libCoal, subsequently modified)
2 //
3 // The WorldForge Project
4 // Copyright (C) 2000, 2001, 2002 The WorldForge Project
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 //
20 // For information about WorldForge and its authors, please contact
21 // the Worldforge Web Site at http://www.worldforge.org.
22 //
23 
24 // Author: Ron Steinke
25 
26 #ifndef WFMATH_POINT_H
27 #define WFMATH_POINT_H
28 
29 #include <wfmath/const.h>
30 
31 #include <memory>
32 #include <iosfwd>
33 
34 #include <cmath>
35 
36 namespace WFMath {
37 
38 template<int dim>
39 Point<dim>& operator+=(Point<dim>& p, const Vector<dim>& v);
40 template<int dim>
41 Point<dim>& operator-=(Point<dim>& p, const Vector<dim>& v);
42 
43 template<int dim>
44 Vector<dim> operator-(const Point<dim>& c1, const Point<dim>& c2);
45 template<int dim>
46 Point<dim> operator+(const Point<dim>& c, const Vector<dim>& v);
47 template<int dim>
48 Point<dim> operator+(const Vector<dim>& v, const Point<dim>& c);
49 template<int dim>
50 Point<dim> operator-(const Point<dim>& c, const Vector<dim>& v);
51 
52 template<int dim>
53 CoordType SquaredDistance(const Point<dim>& p1, const Point<dim>& p2);
54 template<int dim>
55 CoordType Distance(const Point<dim>& p1, const Point<dim>& p2)
56  {return std::sqrt(SquaredDistance(p1, p2));}
57 template<int dim>
58 CoordType SloppyDistance(const Point<dim>& p1, const Point<dim>& p2)
59  {return (p1 - p2).sloppyMag();}
60 
62 template<int dim, template<class, class> class container>
63 Point<dim> Barycenter(const container<Point<dim>, std::allocator<Point<dim> > >& c);
65 
71 template<int dim, template<class, class> class container,
72  template<class, class> class container2>
73 Point<dim> Barycenter(const container<Point<dim>, std::allocator<Point<dim> > >& c,
74  const container2<CoordType, std::allocator<CoordType> >& weights);
75 
76 // This is used a couple of places in the library
77 template<int dim>
78 Point<dim> Midpoint(const Point<dim>& p1, const Point<dim>& p2,
79  CoordType dist = 0.5);
80 
81 template<int dim>
82 std::ostream& operator<<(std::ostream& os, const Point<dim>& m);
83 template<int dim>
84 std::istream& operator>>(std::istream& is, Point<dim>& m);
85 
86 template<typename Shape>
87 class ZeroPrimitive;
88 
90 
94 template<int dim = 3>
95 class Point
96 {
97  friend class ZeroPrimitive<Point<dim> >;
98  public:
100  Point () : m_valid(false) {}
102  Point (const Point& p);
104  explicit Point (const AtlasInType& a);
106  explicit Point(const Vector<dim>& vector);
107 
111  static const Point<dim>& ZERO();
112 
113  friend std::ostream& operator<< <dim>(std::ostream& os, const Point& p);
114  friend std::istream& operator>> <dim>(std::istream& is, Point& p);
115 
117  AtlasOutType toAtlas() const;
119  void fromAtlas(const AtlasInType& a);
120 
121  Point& operator= (const Point& rhs);
122 
123  bool isEqualTo(const Point &p, CoordType epsilon = numeric_constants<CoordType>::epsilon()) const;
124  bool operator== (const Point& rhs) const {return isEqualTo(rhs);}
125  bool operator!= (const Point& rhs) const {return !isEqualTo(rhs);}
126 
127  bool isValid() const {return m_valid;}
129  void setValid(bool valid = true) {m_valid = valid;}
130 
132  Point& setToOrigin();
133 
134  // Operators
135 
136  // Documented in vector.h
137  friend Vector<dim> operator-<dim>(const Point& c1, const Point& c2);
138  friend Point operator+<dim>(const Point& c, const Vector<dim>& v);
139  friend Point operator-<dim>(const Point& c, const Vector<dim>& v);
140  friend Point operator+<dim>(const Vector<dim>& v, const Point& c);
141 
142  friend Point& operator+=<dim>(Point& p, const Vector<dim>& rhs);
143  friend Point& operator-=<dim>(Point& p, const Vector<dim>& rhs);
144 
146  Point& rotate(const RotMatrix<dim>& m, const Point& p)
147  {return (*this = p + Prod(*this - p, m));}
148 
149  // Functions so that Point<> has the generic shape interface
150 
151  size_t numCorners() const {return 1;}
152  Point<dim> getCorner(size_t) const { return *this;}
153  Point<dim> getCenter() const {return *this;}
154 
155  Point shift(const Vector<dim>& v) {return *this += v;}
156  Point moveCornerTo(const Point& p, size_t)
157  {return operator=(p);}
158  Point moveCenterTo(const Point& p) {return operator=(p);}
159 
160  Point& rotateCorner(const RotMatrix<dim>&, size_t)
161  {return *this;}
162  Point& rotateCenter(const RotMatrix<dim>&) {return *this;}
163  Point& rotatePoint(const RotMatrix<dim>& m, const Point& p) {return rotate(m, p);}
164 
165  // 3D rotation functions
166  Point& rotate(const Quaternion& q, const Point& p);
167  Point& rotateCorner(const Quaternion&, size_t)
168  { return *this;}
169  Point& rotateCenter(const Quaternion&) {return *this;}
170  Point& rotatePoint(const Quaternion& q, const Point& p);
171 
172  // The implementations of these lie in axisbox_funcs.h and
173  // ball_funcs.h, to reduce include dependencies
174  AxisBox<dim> boundingBox() const;
175  Ball<dim> boundingSphere() const;
176  Ball<dim> boundingSphereSloppy() const;
177 
178  Point toParentCoords(const Point& origin,
179  const RotMatrix<dim>& rotation = RotMatrix<dim>().identity()) const
180  {return origin + (*this - Point().setToOrigin()) * rotation;}
181  Point toParentCoords(const AxisBox<dim>& coords) const;
182  Point toParentCoords(const RotBox<dim>& coords) const;
183 
184  // toLocal is just like toParent, expect we reverse the order of
185  // translation and rotation and use the opposite sense of the rotation
186  // matrix
187 
188  Point toLocalCoords(const Point& origin,
189  const RotMatrix<dim>& rotation = RotMatrix<dim>().identity()) const
190  {return Point().setToOrigin() + rotation * (*this - origin);}
191  Point toLocalCoords(const AxisBox<dim>& coords) const;
192  Point toLocalCoords(const RotBox<dim>& coords) const;
193 
194  // 3D only
195  Point toParentCoords(const Point& origin, const Quaternion& rotation) const;
196  Point toLocalCoords(const Point& origin, const Quaternion& rotation) const;
197 
198  // Member access
199 
201  CoordType operator[](const int i) const {return m_elem[i];}
203  CoordType& operator[](const int i) {return m_elem[i];}
204 
206  friend CoordType SquaredDistance<dim>(const Point& p1, const Point& p2);
207 
208 // FIXME instatiation problem when declared as friend
209 // template<template<class> class container>
210 // friend Point Barycenter(const container<Point>& c);
211 
213 
219  friend Point<dim> Midpoint<dim>(const Point& p1, const Point& p2, CoordType dist);
220 
221  // 2D/3D stuff
222 
224  Point (CoordType x, CoordType y); // 2D only
226  Point (CoordType x, CoordType y, CoordType z); // 3D only
227 
228  // Label the first three components of the vector as (x,y,z) for
229  // 2D/3D convienience
230 
232  CoordType x() const {return m_elem[0];}
234  CoordType& x() {return m_elem[0];}
236  CoordType y() const {return m_elem[1];}
238  CoordType& y() {return m_elem[1];}
240  CoordType z() const;
242  CoordType& z();
243 
245  Point& polar(CoordType r, CoordType theta);
247  void asPolar(CoordType& r, CoordType& theta) const;
248 
250  Point& polar(CoordType r, CoordType theta, CoordType z);
252  void asPolar(CoordType& r, CoordType& theta, CoordType& z) const;
254  Point& spherical(CoordType r, CoordType theta, CoordType phi);
256  void asSpherical(CoordType& r, CoordType& theta, CoordType& phi) const;
257 
258  const CoordType* elements() const {return m_elem;}
259 
260  private:
261  CoordType m_elem[dim];
262  bool m_valid;
263 };
264 
265 template<>
266 inline CoordType Point<3>::z() const
267 {
268  return m_elem[2];
269 }
270 
271 template<>
272 inline CoordType& Point<3>::z()
273 {
274  return m_elem[2];
275 }
276 
277 template<int dim>
278 inline Point<dim> operator+(const Point<dim>& c, const Vector<dim>& v)
279 {
280  Point<dim> out(c);
281 
282  out += v;
283 
284  return out;
285 }
286 
287 template<int dim>
288 inline Point<dim> operator+(const Vector<dim>& v, const Point<dim>& c)
289 {
290  Point<dim> out(c);
291 
292  out += v;
293 
294  return out;
295 }
296 
297 template<int dim>
298 inline Point<dim> operator-(const Point<dim>& c, const Vector<dim>& v)
299 {
300  Point<dim> out(c);
301 
302  out -= v;
303 
304  return out;
305 }
306 
307 template<>
308 inline Point<2>::Point(CoordType x, CoordType y) : m_valid(true)
309 {
310  m_elem[0] = x;
311  m_elem[1] = y;
312 }
313 
314 template<>
315 inline Point<3>::Point(CoordType x, CoordType y, CoordType z) : m_valid(true)
316 {
317  m_elem[0] = x;
318  m_elem[1] = y;
319  m_elem[2] = z;
320 }
321 
322 } // namespace WFMath
323 
324 #endif // WFMATH_POINT_H