wfmath 1.0.3
A math library for the Worldforge system.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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
36namespace WFMath {
37
38template<int dim>
39Point<dim>& operator+=(Point<dim>& p, const Vector<dim>& v);
40template<int dim>
41Point<dim>& operator-=(Point<dim>& p, const Vector<dim>& v);
42
43template<int dim>
44Vector<dim> operator-(const Point<dim>& c1, const Point<dim>& c2);
45template<int dim>
46Point<dim> operator+(const Point<dim>& c, const Vector<dim>& v);
47template<int dim>
48Point<dim> operator+(const Vector<dim>& v, const Point<dim>& c);
49template<int dim>
50Point<dim> operator-(const Point<dim>& c, const Vector<dim>& v);
51
52template<int dim>
53CoordType SquaredDistance(const Point<dim>& p1, const Point<dim>& p2);
54template<int dim>
55CoordType Distance(const Point<dim>& p1, const Point<dim>& p2)
56 {return std::sqrt(SquaredDistance(p1, p2));}
57template<int dim>
58CoordType SloppyDistance(const Point<dim>& p1, const Point<dim>& p2)
59 {return (p1 - p2).sloppyMag();}
60
62template<int dim, template<class, class> class container>
63Point<dim> Barycenter(const container<Point<dim>, std::allocator<Point<dim> > >& c);
65
71template<int dim, template<class, class> class container,
72 template<class, class> class container2>
73Point<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
77template<int dim>
78Point<dim> Midpoint(const Point<dim>& p1, const Point<dim>& p2,
79 CoordType dist = 0.5);
80
81template<int dim>
82std::ostream& operator<<(std::ostream& os, const Point<dim>& m);
83template<int dim>
84std::istream& operator>>(std::istream& is, Point<dim>& m);
85
86template<typename Shape>
87class ZeroPrimitive;
88
90
94template<int dim = 3>
95class Point
96{
97 friend class ZeroPrimitive<Point<dim> >;
98 public:
100 Point () : m_elem{}, m_valid(false) {};
102 Point (const Point&) = default;
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) = default;
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
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;
198 // Member access
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
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;
243
247 void asPolar(CoordType& r, CoordType& theta) const;
248
252 void asPolar(CoordType& r, CoordType& theta, CoordType& z) const;
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
265template<>
266inline CoordType Point<3>::z() const
267{
268 return m_elem[2];
269}
270
271template<>
272inline CoordType& Point<3>::z()
273{
274 return m_elem[2];
275}
276
277template<int dim>
278inline 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
287template<int dim>
288inline 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
297template<int dim>
298inline 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
307template<>
308inline Point<2>::Point(CoordType x, CoordType y) : m_valid(true)
309{
310 m_elem[0] = x;
311 m_elem[1] = y;
312}
313
314template<>
315inline 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
A dim dimensional point.
Definition: point.h:96
Point & rotate(const RotMatrix< dim > &m, const Point &p)
Rotate about point p.
Definition: point.h:146
void asPolar(CoordType &r, CoordType &theta, CoordType &z) const
3D only: convert a vector to polar coordinates
CoordType x() const
access the first component of a point
Definition: point.h:232
Point(CoordType x, CoordType y)
2D only: construct a point from its (x, y) coordinates
CoordType & y()
access the second component of a point
Definition: point.h:238
Point & spherical(CoordType r, CoordType theta, CoordType phi)
3D only: construct a vector from spherical coordinates
void asSpherical(CoordType &r, CoordType &theta, CoordType &phi) const
3D only: convert a vector to spherical coordinates
CoordType y() const
access the second component of a point
Definition: point.h:236
void setValid(bool valid=true)
make isValid() return true if you've initialized the point by hand
Definition: point.h:129
CoordType & operator[](const int i)
Access the i'th coordinate of the point.
Definition: point.h:203
CoordType & z()
access the third component of a point
static const Point< dim > & ZERO()
Provides a global instance preset to zero.
Definition: point_funcs.h:48
Point(const Point &)=default
Construct a copy of a point.
Point & setToOrigin()
Set point to (0,0,...,0)
Definition: point_funcs.h:56
Point()
Construct an uninitialized point.
Definition: point.h:100
void asPolar(CoordType &r, CoordType &theta) const
2D only: convert a vector to polar coordinates
Point & polar(CoordType r, CoordType theta)
2D only: construct a vector from polar coordinates
Point & polar(CoordType r, CoordType theta, CoordType z)
3D only: construct a vector from polar coordinates
CoordType z() const
access the third component of a point
CoordType & x()
access the first component of a point
Definition: point.h:234
CoordType operator[](const int i) const
Access the i'th coordinate of the point.
Definition: point.h:201
void fromAtlas(const AtlasInType &a)
Set the point's value to that given by an Atlas object.
Definition: atlasconv.h:190
AtlasOutType toAtlas() const
Create an Atlas object from the point.
Definition: atlasconv.h:203
Point(CoordType x, CoordType y, CoordType z)
3D only: construct a point from its (x, y, z) coordinates
A normalized quaternion.
Definition: quaternion.h:36
A dim dimensional rotation matrix. Technically, a member of the group O(dim).
Definition: rotmatrix.h:87
CoordType z() const
Access the third component of a vector.
CoordType x() const
Access the first component of a vector.
Definition: vector.h:313
CoordType y() const
Access the second component of a vector.
Definition: vector.h:317
Utility class for providing zero primitives. This class will only work with simple structures such as...
Definition: zero.h:35
Generic library namespace.
Definition: shape.h:41
double CoordType
Basic floating point type.
Definition: const.h:140
RotMatrix< dim > Prod(const RotMatrix< dim > &m1, const RotMatrix< dim > &m2)
returns m1 * m2
Point< dim > Barycenter(const container< Point< dim >, std::allocator< Point< dim > > > &c)
Find the center of a set of points, all weighted equally.
Definition: point_funcs.h:186
Point< dim > Midpoint(const Point< dim > &p1, const Point< dim > &p2, CoordType dist=0.5)
Definition: point_funcs.h:219