WFMath  1.0.2
axisbox_funcs.h
1 // axisbox_funcs.h (Axis-aligned box implementation)
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 // The implementation of this class is based on the geometric
27 // parts of the Tree and Placement classes from stage/shepherd/sylvanus
28 
29 #ifndef WFMATH_AXIS_BOX_FUNCS_H
30 #define WFMATH_AXIS_BOX_FUNCS_H
31 
32 #include <wfmath/axisbox.h>
33 
34 #include <wfmath/point.h>
35 #include <wfmath/ball.h>
36 
37 namespace WFMath {
38 
39 template<int dim>
40 bool Intersection(const AxisBox<dim>& a1, const AxisBox<dim>& a2, AxisBox<dim>& out)
41 {
42  for(int i = 0; i < dim; ++i) {
43  out.m_low[i] = FloatMax(a1.m_low[i], a2.m_low[i]);
44  out.m_high[i] = FloatMin(a1.m_high[i], a2.m_high[i]);
45  if(out.m_low[i] > out.m_high[i])
46  return false;
47  }
48 
49  out.m_low.setValid(a1.m_low.isValid() && a2.m_low.isValid());
50  out.m_high.setValid(a1.m_high.isValid() && a2.m_high.isValid());
51 
52  return true;
53 }
54 
55 template<int dim>
56 AxisBox<dim> Union(const AxisBox<dim>& a1, const AxisBox<dim>& a2)
57 {
58  AxisBox<dim> out;
59 
60  for(int i = 0; i < dim; ++i) {
61  out.m_low[i] = FloatMin(a1.m_low[i], a2.m_low[i]);
62  out.m_high[i] = FloatMax(a1.m_high[i], a2.m_high[i]);
63  }
64 
65  out.m_low.setValid(a1.m_low.isValid() && a2.m_low.isValid());
66  out.m_high.setValid(a1.m_high.isValid() && a2.m_high.isValid());
67 
68  return out;
69 }
70 
71 template<int dim>
73  bool ordered)
74 {
75  if(ordered) {
76  m_low = p1;
77  m_high = p2;
78  return *this;
79  }
80 
81  for(int i = 0; i < dim; ++i) {
82  if(p1[i] > p2[i]) {
83  m_low[i] = p2[i];
84  m_high[i] = p1[i];
85  }
86  else {
87  m_low[i] = p1[i];
88  m_high[i] = p2[i];
89  }
90  }
91 
92  m_low.setValid();
93  m_high.setValid();
94 
95  return *this;
96 }
97 
98 template<int dim>
99 Point<dim> AxisBox<dim>::getCorner(size_t i) const
100 {
101  if(i < 1)
102  return m_low;
103  if(i >= (1 << dim) - 1)
104  return m_high;
105 
106  Point<dim> out;
107 
108  for(int j = 0; j < dim; ++j)
109  out[j] = (i & (1 << j)) ? m_high[j] : m_low[j];
110 
111  out.setValid(m_low.isValid() && m_high.isValid());
112 
113  return out;
114 }
115 
116 template<int dim>
117 inline Ball<dim> AxisBox<dim>::boundingSphere() const
118 {
119  return Ball<dim>(getCenter(), Distance(m_low, m_high) / 2);
120 }
121 
122 template<int dim>
123 inline Ball<dim> AxisBox<dim>::boundingSphereSloppy() const
124 {
125  return Ball<dim>(getCenter(), SloppyDistance(m_low, m_high) / 2);
126 }
127 
128 
129 template<int dim, template<class, class> class container>
130 AxisBox<dim> BoundingBox(const container<AxisBox<dim>, std::allocator<AxisBox<dim> > >& c)
131 {
132  typename container<AxisBox<dim>, std::allocator<AxisBox<dim> > >::const_iterator i = c.begin(), end = c.end();
133 
134  if(i == end) {
135  return AxisBox<dim>();
136  }
137 
138  Point<dim> low = i->lowCorner(), high = i->highCorner();
139  bool low_valid = low.isValid(), high_valid = high.isValid();
140 
141  while(++i != end) {
142  const Point<dim> &new_low = i->lowCorner(), &new_high = i->highCorner();
143  low_valid = low_valid && new_low.isValid();
144  high_valid = high_valid && new_high.isValid();
145  for(int j = 0; j < dim; ++j) {
146  low[j] = FloatMin(low[j], new_low[j]);
147  high[j] = FloatMax(high[j], new_high[j]);
148  }
149  }
150 
151  low.setValid(low_valid);
152  high.setValid(high_valid);
153 
154  return AxisBox<dim>(low, high, true);
155 }
156 
157 template<int dim, template<class, class> class container>
158 AxisBox<dim> BoundingBox(const container<Point<dim>, std::allocator<Point<dim> > >& c)
159 {
160  typename container<Point<dim>, std::allocator<Point<dim> > >::const_iterator i = c.begin(), end = c.end();
161 
162  if(i == end) {
163  return AxisBox<dim>();
164  }
165 
166  Point<dim> low = *i, high = *i;
167  bool valid = i->isValid();
168 
169  while(++i != end) {
170  valid = valid && i->isValid();
171  for(int j = 0; j < dim; ++j) {
172  low[j] = FloatMin(low[j], (*i)[j]);
173  high[j] = FloatMax(high[j], (*i)[j]);
174  }
175  }
176 
177  low.setValid(valid);
178  high.setValid(valid);
179 
180  return AxisBox<dim>(low, high, true);
181 }
182 
183 // This is here, instead of defined in the class, to
184 // avoid include order problems
185 
186 template<int dim>
187 inline AxisBox<dim> Point<dim>::boundingBox() const
188 {
189  return AxisBox<dim>(*this, *this, true);
190 }
191 
192 template<int dim>
193 Point<dim> Point<dim>::toParentCoords(const AxisBox<dim>& coords) const
194 {
195  return coords.lowCorner() + (*this - Point().setToOrigin());
196 }
197 
198 template<int dim>
199 Point<dim> Point<dim>::toLocalCoords(const AxisBox<dim>& coords) const
200 {
201  return Point().setToOrigin() + (*this - coords.lowCorner());
202 }
203 
204 } // namespace WFMath
205 
206 #endif // WFMATH_AXIS_BOX_FUNCS_H
Generic library namespace.
Definition: atlasconv.h:45
const Point< dim > & lowCorner() const
Get a reference to corner 0.
Definition: axisbox.h:100
A dim dimensional axis-aligned box.
Definition: axisbox.h:62
AxisBox & setCorners(const Point< dim > &p1, const Point< dim > &p2, bool ordered=false)
Set the box to have opposite corners p1 and p2.
Definition: axisbox_funcs.h:72
void setValid(bool valid=true)
make isValid() return true if you&#39;ve initialized the point by hand
Definition: point.h:129
A dim dimensional point.
Definition: const.h:50
AxisBox< dim > BoundingBox(const container< AxisBox< dim >, std::allocator< AxisBox< dim > > > &c)
Get the axis-aligned bounding box for a set of boxes.
Definition: axisbox_funcs.h:130