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