Main Page | Namespace List | Class List | File List | Namespace Members | Class Members

axisbox_funcs.h

00001 // axisbox_funcs.h (Axis-aligned box implementation) 00002 // 00003 // The WorldForge Project 00004 // Copyright (C) 2000, 2001 The WorldForge Project 00005 // 00006 // This program is free software; you can redistribute it and/or modify 00007 // it under the terms of the GNU General Public License as published by 00008 // the Free Software Foundation; either version 2 of the License, or 00009 // (at your option) any later version. 00010 // 00011 // This program is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 // 00016 // You should have received a copy of the GNU General Public License 00017 // along with this program; if not, write to the Free Software 00018 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00019 // 00020 // For information about WorldForge and its authors, please contact 00021 // the Worldforge Web Site at http://www.worldforge.org. 00022 // 00023 00024 // Author: Ron Steinke 00025 00026 // The implementation of this class is based on the geometric 00027 // parts of the Tree and Placement classes from stage/shepherd/sylvanus 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 // FIXME become friend 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 // This is here, instead of defined in the class, to 00194 // avoid include order problems 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 } // namespace WFMath 00215 00216 #endif // WFMATH_AXIS_BOX_FUNCS_H

Generated on Tue Jul 27 21:41:56 2004 for WFMath by doxygen 1.3.7