Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights 1 // Copyright (C) 2010, Guy Barrand. All rights reserved. 2 // See the file tools.license for terms. 2 // See the file tools.license for terms. 3 3 4 #ifndef tools_box3 4 #ifndef tools_box3 5 #define tools_box3 5 #define tools_box3 6 6 7 #include "../mnmx" 7 #include "../mnmx" 8 8 9 //#include <limits> 9 //#include <limits> 10 #include <ostream> 10 #include <ostream> 11 11 12 namespace tools { 12 namespace tools { 13 13 14 template <class VEC3> 14 template <class VEC3> 15 class box3 { 15 class box3 { 16 protected: 16 protected: 17 typedef typename VEC3::elem_t T_t; 17 typedef typename VEC3::elem_t T_t; 18 //static T_t num_max() {return std::numeric_ 18 //static T_t num_max() {return std::numeric_limits<T_t>::max();} //max is a forever pain on Windows. 19 static T_t zero() {return T_t();} 19 static T_t zero() {return T_t();} 20 protected: 20 protected: 21 box3(){ 21 box3(){ 22 //make_empty(); 22 //make_empty(); 23 } 23 } 24 public: 24 public: 25 virtual ~box3() {} 25 virtual ~box3() {} 26 public: 26 public: 27 box3(const box3& a_from) 27 box3(const box3& a_from) 28 :m_min(a_from.m_min) 28 :m_min(a_from.m_min) 29 ,m_max(a_from.m_max) 29 ,m_max(a_from.m_max) 30 {} 30 {} 31 box3& operator=(const box3& a_from){ 31 box3& operator=(const box3& a_from){ 32 m_min = a_from.m_min; 32 m_min = a_from.m_min; 33 m_max = a_from.m_max; 33 m_max = a_from.m_max; 34 return *this; 34 return *this; 35 } 35 } 36 public: 36 public: 37 bool center(VEC3& a_center) const { 37 bool center(VEC3& a_center) const { 38 if(is_empty()) {a_center.set_value(0,0,0); 38 if(is_empty()) {a_center.set_value(0,0,0);return false;} //?? 39 a_center.set_value((m_max[0] + m_min[0])/T 39 a_center.set_value((m_max[0] + m_min[0])/T_t(2), 40 (m_max[1] + m_min[1])/T 40 (m_max[1] + m_min[1])/T_t(2), 41 (m_max[2] + m_min[2])/T 41 (m_max[2] + m_min[2])/T_t(2)); 42 return true; 42 return true; 43 } 43 } 44 44 45 bool set_bounds(const VEC3& a_mn,const VEC3& 45 bool set_bounds(const VEC3& a_mn,const VEC3& a_mx){ 46 if( a_mn[0]>a_mx[0] || a_mn[1]>a_mx[1] || 46 if( a_mn[0]>a_mx[0] || a_mn[1]>a_mx[1] || a_mn[2]>a_mx[2]) return false; 47 m_min = a_mn; 47 m_min = a_mn; 48 m_max = a_mx; 48 m_max = a_mx; 49 return true; 49 return true; 50 } 50 } 51 bool set_bounds(T_t a_mn_x,T_t a_mn_y,T_t a_ 51 bool set_bounds(T_t a_mn_x,T_t a_mn_y,T_t a_mn_z, 52 T_t a_mx_x,T_t a_mx_y,T_t a_ 52 T_t a_mx_x,T_t a_mx_y,T_t a_mx_z){ 53 if( a_mn_x>a_mx_x || a_mn_y>a_mx_y || a_mn 53 if( a_mn_x>a_mx_x || a_mn_y>a_mx_y || a_mn_z>a_mx_z ) return false; 54 m_min.set_value(a_mn_x,a_mn_y,a_mn_z); 54 m_min.set_value(a_mn_x,a_mn_y,a_mn_z); 55 m_max.set_value(a_mx_x,a_mx_y,a_mx_z); 55 m_max.set_value(a_mx_x,a_mx_y,a_mx_z); 56 return true; 56 return true; 57 } 57 } 58 58 59 bool get_size(T_t& a_dx,T_t& a_dy,T_t& a_dz) 59 bool get_size(T_t& a_dx,T_t& a_dy,T_t& a_dz) const { 60 if(is_empty()) {a_dx = 0;a_dy = 0;a_dz = 0 60 if(is_empty()) {a_dx = 0;a_dy = 0;a_dz = 0;return false;} 61 a_dx = m_max[0] - m_min[0]; 61 a_dx = m_max[0] - m_min[0]; 62 a_dy = m_max[1] - m_min[1]; 62 a_dy = m_max[1] - m_min[1]; 63 a_dz = m_max[2] - m_min[2]; 63 a_dz = m_max[2] - m_min[2]; 64 return true; 64 return true; 65 } 65 } 66 66 67 bool is_empty() const {return m_max[0] < m_m 67 bool is_empty() const {return m_max[0] < m_min[0];} 68 68 69 const VEC3& mn() const {return m_min;} 69 const VEC3& mn() const {return m_min;} 70 const VEC3& mx() const {return m_max;} 70 const VEC3& mx() const {return m_max;} 71 71 72 bool back(VEC3& a_min,VEC3& a_min_y,VEC3& a_ 72 bool back(VEC3& a_min,VEC3& a_min_y,VEC3& a_min_xy,VEC3& a_min_x) const { 73 T_t dx,dy,dz; 73 T_t dx,dy,dz; 74 if(!get_size(dx,dy,dz)) return false; //WA 74 if(!get_size(dx,dy,dz)) return false; //WARNING : a_vecs not touched. 75 // back (from m_min, clockwise order looki 75 // back (from m_min, clockwise order looking toward +z) : 76 a_min = m_min; 76 a_min = m_min; 77 a_min_y.set_value (m_min.x() ,m_min.y()+ 77 a_min_y.set_value (m_min.x() ,m_min.y()+dy,m_min.z()); 78 a_min_xy.set_value(m_min.x()+dx,m_min.y()+ 78 a_min_xy.set_value(m_min.x()+dx,m_min.y()+dy,m_min.z()); 79 a_min_x.set_value (m_min.x()+dx,m_min.y() 79 a_min_x.set_value (m_min.x()+dx,m_min.y() ,m_min.z()); 80 return true; 80 return true; 81 } 81 } 82 82 83 bool front(VEC3& a_max,VEC3& a_max_x,VEC3& a 83 bool front(VEC3& a_max,VEC3& a_max_x,VEC3& a_max_xy,VEC3& a_max_y) const { 84 T_t dx,dy,dz; 84 T_t dx,dy,dz; 85 if(!get_size(dx,dy,dz)) return false; //WA 85 if(!get_size(dx,dy,dz)) return false; //WARNING : a_vecs not touched. 86 // front (from m_max, clockwise order look 86 // front (from m_max, clockwise order looking toward -z) : 87 a_max = m_max; 87 a_max = m_max; 88 a_max_x.set_value (m_max.x()-dx,m_max.y() 88 a_max_x.set_value (m_max.x()-dx,m_max.y() ,m_max.z()); 89 a_max_xy.set_value(m_max.x()-dx,m_max.y()- 89 a_max_xy.set_value(m_max.x()-dx,m_max.y()-dy,m_max.z()); 90 a_max_y.set_value (m_max.x() ,m_max.y()- 90 a_max_y.set_value (m_max.x() ,m_max.y()-dy,m_max.z()); 91 return true; 91 return true; 92 } 92 } 93 93 94 void extend_by(const VEC3& a_point) { 94 void extend_by(const VEC3& a_point) { 95 // Extend the boundaries of the box by the 95 // Extend the boundaries of the box by the given point, i.e. make the 96 // point fit inside the box if it isn't al 96 // point fit inside the box if it isn't already so. 97 if(is_empty()) { 97 if(is_empty()) { 98 set_bounds(a_point,a_point); 98 set_bounds(a_point,a_point); 99 } else { 99 } else { 100 m_min.set_value(min_of<T_t>(a_point[0],m 100 m_min.set_value(min_of<T_t>(a_point[0],m_min[0]), 101 min_of<T_t>(a_point[1],m 101 min_of<T_t>(a_point[1],m_min[1]), 102 min_of<T_t>(a_point[2],m 102 min_of<T_t>(a_point[2],m_min[2])); 103 m_max.set_value(max_of<T_t>(a_point[0],m 103 m_max.set_value(max_of<T_t>(a_point[0],m_max[0]), 104 max_of<T_t>(a_point[1],m 104 max_of<T_t>(a_point[1],m_max[1]), 105 max_of<T_t>(a_point[2],m 105 max_of<T_t>(a_point[2],m_max[2])); 106 } 106 } 107 } 107 } 108 108 109 void extend_by(T_t a_x,T_t a_y,T_t a_z) { 109 void extend_by(T_t a_x,T_t a_y,T_t a_z) { 110 // Extend the boundaries of the box by the 110 // Extend the boundaries of the box by the given point, i.e. make the 111 // point fit inside the box if it isn't al 111 // point fit inside the box if it isn't already so. 112 if(is_empty()) { 112 if(is_empty()) { 113 set_bounds(a_x,a_y,a_z,a_x,a_y,a_z); 113 set_bounds(a_x,a_y,a_z,a_x,a_y,a_z); 114 } else { 114 } else { 115 m_min.set_value(min_of<T_t>(a_x,m_min[0] 115 m_min.set_value(min_of<T_t>(a_x,m_min[0]), 116 min_of<T_t>(a_y,m_min[1] 116 min_of<T_t>(a_y,m_min[1]), 117 min_of<T_t>(a_z,m_min[2] 117 min_of<T_t>(a_z,m_min[2])); 118 m_max.set_value(max_of<T_t>(a_x,m_max[0] 118 m_max.set_value(max_of<T_t>(a_x,m_max[0]), 119 max_of<T_t>(a_y,m_max[1] 119 max_of<T_t>(a_y,m_max[1]), 120 max_of<T_t>(a_z,m_max[2] 120 max_of<T_t>(a_z,m_max[2])); 121 } 121 } 122 } 122 } 123 123 124 bool get_cube_size(T_t& a_dx,T_t& a_dy,T_t& 124 bool get_cube_size(T_t& a_dx,T_t& a_dy,T_t& a_dz,T_t(*a_sqrt)(T_t)) const { 125 if(!get_size(a_dx,a_dy,a_dz)) return false 125 if(!get_size(a_dx,a_dy,a_dz)) return false; 126 if((a_dx<=zero())&&(a_dy<=zero())&&(a_dz<= 126 if((a_dx<=zero())&&(a_dy<=zero())&&(a_dz<=zero())) return false; 127 if((a_dx<=zero())&&(a_dy<=zero())) { //dz 127 if((a_dx<=zero())&&(a_dy<=zero())) { //dz not 0 : 128 a_dx = T_t(0.1)*a_dz; 128 a_dx = T_t(0.1)*a_dz; 129 a_dy = T_t(0.1)*a_dz; 129 a_dy = T_t(0.1)*a_dz; 130 } else if((a_dy<=zero())&&(a_dz<=zero())) 130 } else if((a_dy<=zero())&&(a_dz<=zero())) { //dx not 0 : 131 a_dy = T_t(0.1)*a_dx; 131 a_dy = T_t(0.1)*a_dx; 132 a_dz = T_t(0.1)*a_dx; 132 a_dz = T_t(0.1)*a_dx; 133 } else if((a_dz<=zero())&&(a_dx<=zero())) 133 } else if((a_dz<=zero())&&(a_dx<=zero())) { //dy not 0 : 134 a_dz = T_t(0.1)*a_dy; 134 a_dz = T_t(0.1)*a_dy; 135 a_dx = T_t(0.1)*a_dy; 135 a_dx = T_t(0.1)*a_dy; 136 136 137 } else if(a_dx<=zero()) { //dy,dz not 0 : 137 } else if(a_dx<=zero()) { //dy,dz not 0 : 138 a_dx = T_t(0.1)*a_sqrt(a_dy*a_dy+a_dz*a_ 138 a_dx = T_t(0.1)*a_sqrt(a_dy*a_dy+a_dz*a_dz); 139 } else if(a_dy<=zero()) { //dx,dz not 0 : 139 } else if(a_dy<=zero()) { //dx,dz not 0 : 140 a_dy = T_t(0.1)*a_sqrt(a_dx*a_dx+a_dz*a_ 140 a_dy = T_t(0.1)*a_sqrt(a_dx*a_dx+a_dz*a_dz); 141 } else if(a_dz<=zero()) { //dx,dy not 0 : 141 } else if(a_dz<=zero()) { //dx,dy not 0 : 142 a_dz = T_t(0.1)*a_sqrt(a_dx*a_dx+a_dy*a_ 142 a_dz = T_t(0.1)*a_sqrt(a_dx*a_dx+a_dy*a_dy); 143 } 143 } 144 return true; 144 return true; 145 } 145 } 146 146 147 //NOTE : print is a Python keyword. 147 //NOTE : print is a Python keyword. 148 void dump(std::ostream& a_out) { 148 void dump(std::ostream& a_out) { 149 T_t dx,dy,dz; 149 T_t dx,dy,dz; 150 if(!get_size(dx,dy,dz)) { 150 if(!get_size(dx,dy,dz)) { 151 a_out << "box is empty." << std::endl; 151 a_out << "box is empty." << std::endl; 152 } else { 152 } else { 153 a_out << " size " << dx << " " << dy << 153 a_out << " size " << dx << " " << dy << " " << dz << std::endl; 154 } 154 } 155 a_out << " min " << m_min[0] << " " << m_m 155 a_out << " min " << m_min[0] << " " << m_min[1] << " " << m_min[2] << std::endl; 156 a_out << " max " << m_max[0] << " " << m_m 156 a_out << " max " << m_max[0] << " " << m_max[1] << " " << m_max[2] << std::endl; 157 VEC3 c; 157 VEC3 c; 158 center(c); 158 center(c); 159 a_out << " center " << c[0] << " " << c[1] 159 a_out << " center " << c[0] << " " << c[1] << " " << c[2] << std::endl; 160 } 160 } 161 161 162 protected: 162 protected: 163 VEC3 m_min; 163 VEC3 m_min; 164 VEC3 m_max; 164 VEC3 m_max; 165 }; 165 }; 166 166 167 } 167 } 168 168 169 #endif 169 #endif