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