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
37namespace WFMath {
38
39template<int dim>
40bool 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
55template<int dim>
56AxisBox<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
71template<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
98template<int dim>
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
116template<int dim>
117inline Ball<dim> AxisBox<dim>::boundingSphere() const
118{
119 return Ball<dim>(getCenter(), Distance(m_low, m_high) / 2);
120}
121
122template<int dim>
123inline Ball<dim> AxisBox<dim>::boundingSphereSloppy() const
124{
125 return Ball<dim>(getCenter(), SloppyDistance(m_low, m_high) / 2);
126}
127
128
129template<int dim, template<class, class> class container>
130AxisBox<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
157template<int dim, template<class, class> class container>
158AxisBox<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
186template<int dim>
187inline AxisBox<dim> Point<dim>::boundingBox() const
188{
189 return AxisBox<dim>(*this, *this, true);
190}
191
192template<int dim>
193Point<dim> Point<dim>::toParentCoords(const AxisBox<dim>& coords) const
194{
195 return coords.lowCorner() + (*this - Point().setToOrigin());
196}
197
198template<int dim>
199Point<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
A dim dimensional axis-aligned box.
Definition const.h:48
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
A dim dimensional point.
Definition point.h:96
void setValid(bool valid=true)
make isValid() return true if you've initialized the point by hand
Definition point.h:129
Generic library namespace.
Definition atlasconv.h:45
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