WFMath  1.0.2
rotbox.h
1 // rotbox.h (A box with arbitrary orientation)
2 //
3 // The WorldForge Project
4 // Copyright (C) 2000, 2001 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_ROT_BOX_H
27 #define WFMATH_ROT_BOX_H
28 
29 #include <wfmath/point.h>
30 #include <wfmath/rotmatrix.h>
31 #include <wfmath/intersect_decls.h>
32 
33 namespace WFMath {
34 
35 template<int dim>
36 std::ostream& operator<<(std::ostream& os, const RotBox<dim>& r);
37 template<int dim>
38 std::istream& operator>>(std::istream& is, RotBox<dim>& r);
39 
41 
45 template<int dim = 3>
46 class RotBox
47 {
48  public:
50  RotBox() : m_corner0(), m_size(), m_orient() {}
52 
57  RotBox(const Point<dim>& p, const Vector<dim>& size,
58  const RotMatrix<dim>& orientation) : m_corner0(p), m_size(size),
59  m_orient(orientation) {}
61  RotBox(const RotBox& b) : m_corner0(b.m_corner0), m_size(b.m_size),
62  m_orient(b.m_orient) {}
64  explicit RotBox(const AtlasInType& a);
65 
66  ~RotBox() {}
67 
69  AtlasOutType toAtlas() const;
71  void fromAtlas(const AtlasInType& a);
72 
73  friend std::ostream& operator<< <dim>(std::ostream& os, const RotBox& r);
74  friend std::istream& operator>> <dim>(std::istream& is, RotBox& r);
75 
76  RotBox& operator=(const RotBox& s);
77 
78  bool isEqualTo(const RotBox& b, CoordType epsilon = numeric_constants<CoordType>::epsilon()) const;
79 
80  bool operator==(const RotBox& b) const {return isEqualTo(b);}
81  bool operator!=(const RotBox& b) const {return !isEqualTo(b);}
82 
83  bool isValid() const {return m_corner0.isValid() && m_size.isValid()
84  && m_orient.isValid();}
85 
86  // Descriptive characteristics
87 
88  size_t numCorners() const {return 1 << dim;}
89  Point<dim> getCorner(size_t i) const;
90  Point<dim> getCenter() const {return m_corner0 + Prod(m_size / 2, m_orient);}
91 
93  const Point<dim>& corner0() const {return m_corner0;}
95  Point<dim>& corner0() {return m_corner0;}
97  const Vector<dim>& size() const {return m_size;}
99  Vector<dim>& size() {return m_size;}
101  const RotMatrix<dim>& orientation() const {return m_orient;}
103  RotMatrix<dim>& orientation() {return m_orient;}
104 
105  // Movement functions
106 
107  RotBox& shift(const Vector<dim>& v)
108  {m_corner0 += v; return *this;}
109  RotBox& moveCornerTo(const Point<dim>& p, size_t corner)
110  {return shift(p - getCorner(corner));}
111  RotBox& moveCenterTo(const Point<dim>& p)
112  {return shift(p - getCenter());}
113 
114  RotBox& rotateCorner(const RotMatrix<dim>& m, size_t corner)
115  {rotatePoint(m, getCorner(corner)); return *this;}
116  RotBox& rotateCenter(const RotMatrix<dim>& m)
117  {rotatePoint(m, getCenter()); return *this;}
118  RotBox& rotatePoint(const RotMatrix<dim>& m, const Point<dim>& p)
119  {m_orient = Prod(m_orient, m); m_corner0.rotate(m, p); return *this;}
120 
121  // 3D rotation functions
122  RotBox& rotateCorner(const Quaternion& q, size_t corner);
123  RotBox& rotateCenter(const Quaternion& q);
124  RotBox& rotatePoint(const Quaternion& q, const Point<dim>& p);
125 
126  // Intersection functions
127 
128  AxisBox<dim> boundingBox() const;
129  Ball<dim> boundingSphere() const
130  {return Ball<dim>(getCenter(), m_size.mag() / 2);}
131  Ball<dim> boundingSphereSloppy() const
132  {return Ball<dim>(getCenter(), m_size.sqrMag() / 2);}
133 
134  RotBox toParentCoords(const Point<dim>& origin,
135  const RotMatrix<dim>& rotation = RotMatrix<dim>().identity()) const
136  {return RotBox(m_corner0.toParentCoords(origin, rotation), m_size,
137  m_orient * rotation);}
138  RotBox toParentCoords(const AxisBox<dim>& coords) const
139  {return RotBox(m_corner0.toParentCoords(coords), m_size, m_orient);}
140  RotBox toParentCoords(const RotBox<dim>& coords) const
141  {return RotBox(m_corner0.toParentCoords(coords), m_size,
142  m_orient * coords.m_orient);}
143 
144  // toLocal is just like toParent, expect we reverse the order of
145  // translation and rotation and use the opposite sense of the rotation
146  // matrix
147 
148  RotBox toLocalCoords(const Point<dim>& origin,
149  const RotMatrix<dim>& rotation = RotMatrix<dim>().identity()) const
150  {return RotBox(m_corner0.toLocalCoords(origin, rotation), m_size,
151  rotation * m_orient);}
152  RotBox toLocalCoords(const AxisBox<dim>& coords) const
153  {return RotBox(m_corner0.toLocalCoords(coords), m_size, m_orient);}
154  RotBox toLocalCoords(const RotBox<dim>& coords) const
155  {return RotBox(m_corner0.toLocalCoords(coords), m_size,
156  coords.m_orient * m_orient);}
157 
158  // 3D only
159  RotBox toParentCoords(const Point<dim>& origin, const Quaternion& rotation) const;
160  RotBox toLocalCoords(const Point<dim>& origin, const Quaternion& rotation) const;
161 
162  friend bool Intersect<dim>(const RotBox& r, const Point<dim>& p, bool proper);
163  friend bool Contains<dim>(const Point<dim>& p, const RotBox& r, bool proper);
164 
165  friend bool Intersect<dim>(const RotBox& r, const AxisBox<dim>& b, bool proper);
166  friend bool Contains<dim>(const RotBox& r, const AxisBox<dim>& b, bool proper);
167  friend bool Contains<dim>(const AxisBox<dim>& b, const RotBox& r, bool proper);
168 
169  friend bool Intersect<dim>(const RotBox& r, const Ball<dim>& b, bool proper);
170  friend bool Contains<dim>(const RotBox& r, const Ball<dim>& b, bool proper);
171  friend bool Contains<dim>(const Ball<dim>& b, const RotBox& r, bool proper);
172 
173  friend bool Intersect<dim>(const RotBox& r, const Segment<dim>& s, bool proper);
174  friend bool Contains<dim>(const RotBox& r, const Segment<dim>& s, bool proper);
175  friend bool Contains<dim>(const Segment<dim>& s, const RotBox& r, bool proper);
176 
177  friend bool Intersect<dim>(const RotBox& r1, const RotBox& r2, bool proper);
178  friend bool Contains<dim>(const RotBox& outer, const RotBox& inner, bool proper);
179 
180  friend bool Intersect<dim>(const Polygon<dim>& p, const RotBox& r, bool proper);
181  friend bool Contains<dim>(const Polygon<dim>& p, const RotBox& r, bool proper);
182  friend bool Contains<dim>(const RotBox& r, const Polygon<dim>& p, bool proper);
183 
184  private:
185 
186  Point<dim> m_corner0;
187  Vector<dim> m_size;
188  RotMatrix<dim> m_orient;
189 };
190 
191 template<int dim>
193 {
194  m_corner0 = a.m_corner0;
195  m_size = a.m_size;
196  m_orient = a.m_orient;
197 
198  return *this;
199 }
200 
201 template<int dim>
202 inline bool RotBox<dim>::isEqualTo(const RotBox<dim>& b, CoordType epsilon) const
203 {
204  return Equal(m_corner0, b.m_corner0, epsilon)
205  && Equal(m_size, b.m_size, epsilon)
206  && Equal(m_orient, b.m_orient, epsilon);
207 }
208 
209 } // namespace WFMath
210 
211 #endif // WFMATH_ROT_BOX_H
bool Equal(const C &c1, const C &c2, CoordType epsilon=numeric_constants< CoordType >::epsilon())
Test for equality up to precision epsilon.
Definition: const.h:158
Generic library namespace.
Definition: atlasconv.h:45
const Vector< dim > & size() const
returns the size of the box
Definition: rotbox.h:97
A dim dimensional axis-aligned box.
Definition: axisbox.h:62
const Point< dim > & corner0() const
returns the base corner of the box
Definition: rotbox.h:93
RotBox()
construct an uninitialized box
Definition: rotbox.h:50
void fromAtlas(const AtlasInType &a)
Set the box&#39;s value to that given by an Atlas object.
Definition: atlasconv.h:409
RotMatrix< dim > & orientation()
returns the orientation of the box
Definition: rotbox.h:103
A dim dimensional rotation matrix. Technically, a member of the group O(dim).
Definition: const.h:53
A dim dimensional box, lying at an arbitrary angle.
Definition: const.h:52
Vector< dim > & size()
returns the size of the box
Definition: rotbox.h:99
A polygon, all of whose points lie in a plane, embedded in dim dimensions.
Definition: const.h:51
RotBox(const Point< dim > &p, const Vector< dim > &size, const RotMatrix< dim > &orientation)
construct a box from the given parameters
Definition: rotbox.h:57
RotBox(const RotBox &b)
construct a copy of the box
Definition: rotbox.h:61
A dim dimensional vector.
Definition: const.h:55
const RotMatrix< dim > & orientation() const
returns the orientation of the box
Definition: rotbox.h:101
float CoordType
Basic floating point type.
Definition: const.h:140
A line segment embedded in dim dimensions.
Definition: const.h:54
AtlasOutType toAtlas() const
Create an Atlas object from the box.
Definition: atlasconv.h:437
Point< dim > & corner0()
returns the base corner of the box
Definition: rotbox.h:95
A normalized quaterion.
Definition: quaternion.h:35
RotMatrix< dim > Prod(const RotMatrix< dim > &m1, const RotMatrix< dim > &m2)
returns m1 * m2
Definition: rotmatrix_funcs.h:89
A dim dimensional point.
Definition: const.h:50
A dim dimensional ball.
Definition: ball.h:34