00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
#ifndef WFMATH_AXIS_BOX_FUNCS_H
00030
#define WFMATH_AXIS_BOX_FUNCS_H
00031
00032
#include <wfmath/const.h>
00033
#include <wfmath/vector.h>
00034
#include <wfmath/point.h>
00035
#include <wfmath/axisbox.h>
00036
#include <wfmath/ball.h>
00037
00038
namespace WFMath {
00039
00040
template<const
int dim>
00041
inline bool AxisBox<dim>::isEqualTo(
const AxisBox<dim>& b,
double epsilon)
const
00042
{
00043
return Equal(m_low, b.m_low, epsilon)
00044 &&
Equal(m_high, b.m_high, epsilon);
00045 }
00046
00047
template<const
int dim>
00048
bool Intersection(
const AxisBox<dim>& a1,
const AxisBox<dim>& a2, AxisBox<dim>& out)
00049 {
00050
for(
int i = 0; i < dim; ++i) {
00051 out.m_low[i] = FloatMax(a1.m_low[i], a2.m_low[i]);
00052 out.m_high[i] = FloatMin(a1.m_high[i], a2.m_high[i]);
00053
if(out.m_low[i] > out.m_high[i])
00054
return false;
00055 }
00056
00057 out.m_low.setValid(a1.m_low.isValid() && a2.m_low.isValid());
00058 out.m_high.setValid(a1.m_high.isValid() && a2.m_high.isValid());
00059
00060
return true;
00061 }
00062
00063
template<const
int dim>
00064 AxisBox<dim> Union(
const AxisBox<dim>& a1,
const AxisBox<dim>& a2)
00065 {
00066 AxisBox<dim> out;
00067
00068
for(
int i = 0; i < dim; ++i) {
00069 out.m_low[i] = FloatMin(a1.m_low[i], a2.m_low[i]);
00070 out.m_high[i] = FloatMax(a1.m_high[i], a2.m_high[i]);
00071 }
00072
00073 out.m_low.setValid(a1.m_low.isValid() && a2.m_low.isValid());
00074 out.m_high.setValid(a1.m_high.isValid() && a2.m_high.isValid());
00075
00076
return out;
00077 }
00078
00079
template<const
int dim>
00080 AxisBox<dim>&
AxisBox<dim>::setCorners(
const Point<dim>& p1,
const Point<dim>& p2,
00081
bool ordered)
00082 {
00083
if(ordered) {
00084 m_low = p1;
00085 m_high = p2;
00086
return *
this;
00087 }
00088
00089
for(
int i = 0; i < dim; ++i) {
00090
if(p1[i] > p2[i]) {
00091 m_low[i] = p2[i];
00092 m_high[i] = p1[i];
00093 }
00094
else {
00095 m_low[i] = p1[i];
00096 m_high[i] = p2[i];
00097 }
00098 }
00099
00100 m_low.setValid();
00101 m_high.setValid();
00102
00103
return *
this;
00104 }
00105
00106
template<const
int dim>
00107
Point<dim> AxisBox<dim>::getCorner(
int i)
const
00108
{
00109 assert(i >= 0 && i < (1 << dim));
00110
00111
if(i == 0)
00112
return m_low;
00113
if(i == (1 << dim) - 1)
00114
return m_high;
00115
00116
Point<dim> out;
00117
00118
for(
int j = 0; j < dim; ++j)
00119 out[j] = (i & (1 << j)) ? m_high[j] : m_low[j];
00120
00121 out.
setValid(m_low.isValid() && m_high.isValid());
00122
00123
return out;
00124 }
00125
00126
template<const
int dim>
00127
inline Ball<dim> AxisBox<dim>::boundingSphere()
const
00128
{
00129
return Ball<dim>(getCenter(), Distance(m_low, m_high) / 2);
00130 }
00131
00132
template<const
int dim>
00133
inline Ball<dim> AxisBox<dim>::boundingSphereSloppy()
const
00134
{
00135
return Ball<dim>(getCenter(), SloppyDistance(m_low, m_high) / 2);
00136 }
00137
00138
00139
#ifndef WFMATH_NO_TEMPLATES_AS_TEMPLATE_PARAMETERS
00140
template<const
int dim,
template<
class>
class container>
00141 AxisBox<dim> BoundingBox(
const container<
AxisBox<dim> >& c)
00142 {
00143
00144
00145
typename container<AxisBox<dim> >::const_iterator i = c.begin(), end = c.end();
00146
00147 assert(i != end);
00148
00149
Point<dim> low = i->lowCorner(), high = i->highCorner();
00150
bool low_valid = low.
isValid(), high_valid = high.isValid();
00151
00152
while(++i != end) {
00153
const Point<dim> &new_low = i->lowCorner(), &new_high = i->highCorner();
00154 low_valid = low_valid && new_low.
isValid();
00155 high_valid = high_valid && new_high.isValid();
00156
for(
int j = 0; j < dim; ++j) {
00157 low[j] = FloatMin(low[j], new_low[j]);
00158 high[j] = FloatMax(high[j], new_high[j]);
00159 }
00160 }
00161
00162 low.
setValid(low_valid);
00163 high.setValid(high_valid);
00164
00165
return AxisBox<dim>(low, high,
true);
00166 }
00167
00168
template<const
int dim,
template<
class>
class container>
00169 AxisBox<dim> BoundingBox(
const container<
Point<dim> >& c)
00170 {
00171
typename container<Point<dim> >::const_iterator i = c.begin(), end = c.end();
00172
00173 assert(i != end);
00174
00175
Point<dim> low = *i, high = *i;
00176
bool valid = i->
isValid();
00177
00178
while(++i != end) {
00179 valid = valid && i->
isValid();
00180
for(
int j = 0; j < dim; ++j) {
00181 low[j] = FloatMin(low[j], (*i)[j]);
00182 high[j] = FloatMax(high[j], (*i)[j]);
00183 }
00184 }
00185
00186 low.
setValid(valid);
00187 high.
setValid(valid);
00188
00189
return AxisBox<dim>(low, high,
true);
00190 }
00191
#endif
00192
00193
00194
00195
00196
template<const
int dim>
00197
inline AxisBox<dim> Point<dim>::boundingBox()
const
00198
{
00199
return AxisBox<dim>(*
this, *
this,
true);
00200 }
00201
00202
template<const
int dim>
00203 Point<dim> Point<dim>::toParentCoords(
const AxisBox<dim>& coords)
const
00204
{
00205
return coords.lowCorner() + (*
this - Point().setToOrigin());
00206 }
00207
00208
template<const
int dim>
00209 Point<dim> Point<dim>::toLocalCoords(
const AxisBox<dim>& coords)
const
00210
{
00211
return Point().setToOrigin() + (*
this - coords.lowCorner());
00212 }
00213
00214 }
00215
00216
#endif // WFMATH_AXIS_BOX_FUNCS_H