Geant4 Cross Reference |
1 // ******************************************* 1 // ******************************************************************** 2 // * License and Disclaimer 2 // * License and Disclaimer * 3 // * 3 // * * 4 // * The Geant4 software is copyright of th 4 // * The Geant4 software is copyright of the Copyright Holders of * 5 // * the Geant4 Collaboration. It is provided 5 // * the Geant4 Collaboration. It is provided under the terms and * 6 // * conditions of the Geant4 Software License 6 // * conditions of the Geant4 Software License, included in the file * 7 // * LICENSE and available at http://cern.ch/ 7 // * LICENSE and available at http://cern.ch/geant4/license . These * 8 // * include a list of copyright holders. 8 // * include a list of copyright holders. * 9 // * 9 // * * 10 // * Neither the authors of this software syst 10 // * Neither the authors of this software system, nor their employing * 11 // * institutes,nor the agencies providing fin 11 // * institutes,nor the agencies providing financial support for this * 12 // * work make any representation or warran 12 // * work make any representation or warranty, express or implied, * 13 // * regarding this software system or assum 13 // * regarding this software system or assume any liability for its * 14 // * use. Please see the license in the file 14 // * use. Please see the license in the file LICENSE and URL above * 15 // * for the full disclaimer and the limitatio 15 // * for the full disclaimer and the limitation of liability. * 16 // * 16 // * * 17 // * This code implementation is the result 17 // * This code implementation is the result of the scientific and * 18 // * technical work of the GEANT4 collaboratio 18 // * technical work of the GEANT4 collaboration. * 19 // * By using, copying, modifying or distri 19 // * By using, copying, modifying or distributing the software (or * 20 // * any work based on the software) you ag 20 // * any work based on the software) you agree to acknowledge its * 21 // * use in resulting scientific publicati 21 // * use in resulting scientific publications, and indicate your * 22 // * acceptance of all terms of the Geant4 Sof 22 // * acceptance of all terms of the Geant4 Software license. * 23 // ******************************************* 23 // ******************************************************************** 24 // 24 // 25 // 25 // 26 // Author: HoangTRAN, 20/2/2019 26 // Author: HoangTRAN, 20/2/2019 27 #include "G4DNABoundingBox.hh" 27 #include "G4DNABoundingBox.hh" 28 #include <array> 28 #include <array> 29 #include "G4UnitsTable.hh" 29 #include "G4UnitsTable.hh" 30 using std::array; 30 using std::array; 31 using std::initializer_list; 31 using std::initializer_list; 32 //....oooOO0OOooo........oooOO0OOooo........oo 32 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 33 33 34 G4DNABoundingBox::G4DNABoundingBox(G4DNABoundi 34 G4DNABoundingBox::G4DNABoundingBox(G4DNABoundingBox&& rhs) noexcept 35 { 35 { 36 fxhi = rhs.fxhi; 36 fxhi = rhs.fxhi; 37 fxlo = rhs.fxlo; 37 fxlo = rhs.fxlo; 38 fyhi = rhs.fyhi; 38 fyhi = rhs.fyhi; 39 fylo = rhs.fylo; 39 fylo = rhs.fylo; 40 fzhi = rhs.fzhi; 40 fzhi = rhs.fzhi; 41 fzlo = rhs.fzlo; 41 fzlo = rhs.fzlo; 42 } 42 } 43 ////....oooOO0OOooo........oooOO0OOooo........ 43 ////....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 44 44 45 G4DNABoundingBox::G4DNABoundingBox(const initi 45 G4DNABoundingBox::G4DNABoundingBox(const initializer_list<G4double>& l) 46 { 46 { 47 fxhi = 0.; 47 fxhi = 0.; 48 fxlo = 0.; 48 fxlo = 0.; 49 fyhi = 0.; 49 fyhi = 0.; 50 fylo = 0.; 50 fylo = 0.; 51 fzhi = 0.; 51 fzhi = 0.; 52 fzlo = 0.; 52 fzlo = 0.; 53 std::copy(l.begin(), l.end(), &fxhi); 53 std::copy(l.begin(), l.end(), &fxhi); 54 } 54 } 55 55 56 //....oooOO0OOooo........oooOO0OOooo........oo 56 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 57 57 58 G4DNABoundingBox& G4DNABoundingBox::operator=( 58 G4DNABoundingBox& G4DNABoundingBox::operator=(G4DNABoundingBox&& rhs) noexcept 59 { 59 { 60 fxhi = rhs.fxhi; 60 fxhi = rhs.fxhi; 61 fxlo = rhs.fxlo; 61 fxlo = rhs.fxlo; 62 fyhi = rhs.fyhi; 62 fyhi = rhs.fyhi; 63 fylo = rhs.fylo; 63 fylo = rhs.fylo; 64 fzhi = rhs.fzhi; 64 fzhi = rhs.fzhi; 65 fzlo = rhs.fzlo; 65 fzlo = rhs.fzlo; 66 return *this; 66 return *this; 67 } 67 } 68 68 69 G4double G4DNABoundingBox::Volume() const 69 G4double G4DNABoundingBox::Volume() const 70 { 70 { 71 auto LengthY = this->Getyhi() - this->Getylo 71 auto LengthY = this->Getyhi() - this->Getylo(); 72 auto LengthX = this->Getxhi() - this->Getxlo 72 auto LengthX = this->Getxhi() - this->Getxlo(); 73 auto LengthZ = this->Getzhi() - this->Getzlo 73 auto LengthZ = this->Getzhi() - this->Getzlo(); 74 G4double V = LengthY * LengthX * LengthZ; 74 G4double V = LengthY * LengthX * LengthZ; 75 return V; 75 return V; 76 } 76 } 77 77 78 //....oooOO0OOooo........oooOO0OOooo........oo 78 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 79 79 80 void G4DNABoundingBox::resize(G4ThreeVector pi 80 void G4DNABoundingBox::resize(G4ThreeVector pics[8]) 81 { 81 { 82 for(size_t i = 0; i < 8; i++) 82 for(size_t i = 0; i < 8; i++) 83 { 83 { 84 const G4ThreeVector& point = pics[i]; 84 const G4ThreeVector& point = pics[i]; 85 if(point.x() < fxlo) 85 if(point.x() < fxlo) 86 { 86 { 87 fxlo = point.x(); 87 fxlo = point.x(); 88 } 88 } 89 if(point.x() > fxhi) 89 if(point.x() > fxhi) 90 { 90 { 91 fxhi = point.x(); 91 fxhi = point.x(); 92 } 92 } 93 93 94 if(point.y() < fylo) 94 if(point.y() < fylo) 95 { 95 { 96 fylo = point.y(); 96 fylo = point.y(); 97 } 97 } 98 if(point.y() > fyhi) 98 if(point.y() > fyhi) 99 { 99 { 100 fyhi = point.y(); 100 fyhi = point.y(); 101 } 101 } 102 102 103 if(point.z() < fzlo) 103 if(point.z() < fzlo) 104 { 104 { 105 fzlo = point.z(); 105 fzlo = point.z(); 106 } 106 } 107 if(point.z() > fzhi) 107 if(point.z() > fzhi) 108 { 108 { 109 fzhi = point.z(); 109 fzhi = point.z(); 110 } 110 } 111 } 111 } 112 } 112 } 113 113 114 //-------------------------------------------- 114 //------------------------------------------------------------------------------ 115 115 116 G4DNABoundingBox G4DNABoundingBox::translate(c 116 G4DNABoundingBox G4DNABoundingBox::translate(const G4ThreeVector& trans) const 117 { 117 { 118 G4DNABoundingBox output; 118 G4DNABoundingBox output; 119 119 120 output.fxhi = fxhi + trans.x(); 120 output.fxhi = fxhi + trans.x(); 121 output.fxlo = fxlo + trans.x(); 121 output.fxlo = fxlo + trans.x(); 122 122 123 output.fyhi = fyhi + trans.y(); 123 output.fyhi = fyhi + trans.y(); 124 output.fylo = fylo + trans.x(); 124 output.fylo = fylo + trans.x(); 125 125 126 output.fzhi = fzhi + trans.z(); 126 output.fzhi = fzhi + trans.z(); 127 output.fzlo = fzlo + trans.z(); 127 output.fzlo = fzlo + trans.z(); 128 128 129 return output; 129 return output; 130 } 130 } 131 //....oooOO0OOooo........oooOO0OOooo........oo 131 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 132 132 133 G4bool G4DNABoundingBox::contains(const G4DNAB 133 G4bool G4DNABoundingBox::contains(const G4DNABoundingBox& other) const 134 { 134 { 135 return fxlo <= other.fxlo && fxhi >= other.f 135 return fxlo <= other.fxlo && fxhi >= other.fxhi && fylo <= other.fylo && 136 fyhi >= other.fyhi && fzlo <= other.f 136 fyhi >= other.fyhi && fzlo <= other.fzlo && fzhi >= other.fzhi; 137 } 137 } 138 138 139 //....oooOO0OOooo........oooOO0OOooo........oo 139 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 140 140 141 G4bool G4DNABoundingBox::contains(const G4Thre 141 G4bool G4DNABoundingBox::contains(const G4ThreeVector& point) const 142 { 142 { 143 return fxlo <= point.x() && fxhi >= point.x( 143 return fxlo <= point.x() && fxhi >= point.x() && fylo <= point.y() && 144 fyhi >= point.y() && fzlo <= point.z( 144 fyhi >= point.y() && fzlo <= point.z() && fzhi >= point.z(); 145 } 145 } 146 146 147 //....oooOO0OOooo........oooOO0OOooo........oo 147 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 148 148 149 G4bool G4DNABoundingBox::overlap(const G4DNABo 149 G4bool G4DNABoundingBox::overlap(const G4DNABoundingBox& other, 150 G4DNABounding 150 G4DNABoundingBox* out) const 151 { 151 { 152 if(contains(other)) 152 if(contains(other)) 153 { 153 { 154 *out = other; 154 *out = other; 155 return true; 155 return true; 156 } 156 } 157 if(other.contains(*this)) << 157 else if(other.contains(*this)) 158 { 158 { 159 *out = *this; 159 *out = *this; 160 return true; 160 return true; 161 } 161 } 162 162 163 // Check if there is no intersection 163 // Check if there is no intersection 164 if(fxhi < other.fxlo || fxlo > other.fxhi || 164 if(fxhi < other.fxlo || fxlo > other.fxhi || fyhi < other.fylo || 165 fylo > other.fyhi || fzhi < other.fzlo || 165 fylo > other.fyhi || fzhi < other.fzlo || fzlo > other.fzhi) 166 { 166 { 167 *out = invalid; 167 *out = invalid; 168 return false; 168 return false; 169 } 169 } 170 170 171 G4double upperX = std::min(fxhi, other.fxhi) 171 G4double upperX = std::min(fxhi, other.fxhi); 172 G4double upperY = std::min(fyhi, other.fyhi) 172 G4double upperY = std::min(fyhi, other.fyhi); 173 G4double upperZ = std::min(fzhi, other.fzhi) 173 G4double upperZ = std::min(fzhi, other.fzhi); 174 174 175 G4double lowerX = std::max(fxlo, other.fxlo) 175 G4double lowerX = std::max(fxlo, other.fxlo); 176 G4double lowerY = std::max(fylo, other.fylo) 176 G4double lowerY = std::max(fylo, other.fylo); 177 G4double lowerZ = std::max(fzlo, other.fzlo) 177 G4double lowerZ = std::max(fzlo, other.fzlo); 178 178 179 *out = G4DNABoundingBox{ upperX, lowerX, upp 179 *out = G4DNABoundingBox{ upperX, lowerX, upperY, lowerY, upperZ, lowerZ }; 180 return true; 180 return true; 181 } 181 } 182 182 183 //....oooOO0OOooo........oooOO0OOooo........oo 183 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 184 184 185 G4bool G4DNABoundingBox::overlap(const G4Three 185 G4bool G4DNABoundingBox::overlap(const G4ThreeVector& query, 186 const G4doubl 186 const G4double& Radius) const 187 { 187 { 188 G4double x = query.x() - this->middlePoint() 188 G4double x = query.x() - this->middlePoint().x(); 189 G4double y = query.y() - this->middlePoint() 189 G4double y = query.y() - this->middlePoint().y(); 190 G4double z = query.z() - this->middlePoint() 190 G4double z = query.z() - this->middlePoint().z(); 191 191 192 x = std::abs(x); 192 x = std::abs(x); 193 y = std::abs(y); 193 y = std::abs(y); 194 z = std::abs(z); 194 z = std::abs(z); 195 195 196 if((x > (Radius + this->halfSideLengthInX()) 196 if((x > (Radius + this->halfSideLengthInX())) || 197 (y > (Radius + this->halfSideLengthInY()) 197 (y > (Radius + this->halfSideLengthInY())) || 198 (z > (Radius + this->halfSideLengthInZ()) 198 (z > (Radius + this->halfSideLengthInZ()))) 199 { 199 { 200 return false; // 200 return false; // 201 } 201 } 202 G4int num_less_extent = static_cast<int>(x < << 202 G4int num_less_extent = (x < this->halfSideLengthInX()) + 203 static_cast<int>(y < << 203 (y < this->halfSideLengthInY()) + 204 static_cast<int>(z < << 204 (z < this->halfSideLengthInZ()); 205 205 206 if(num_less_extent > 1) 206 if(num_less_extent > 1) 207 { 207 { 208 return true; 208 return true; 209 } 209 } 210 210 211 x = std::max(x - this->halfSideLengthInX(), 211 x = std::max(x - this->halfSideLengthInX(), 0.0); 212 y = std::max(y - this->halfSideLengthInY(), 212 y = std::max(y - this->halfSideLengthInY(), 0.0); 213 z = std::max(z - this->halfSideLengthInZ(), 213 z = std::max(z - this->halfSideLengthInZ(), 0.0); 214 214 215 G4double norm = std::sqrt(x * x + y * y + z 215 G4double norm = std::sqrt(x * x + y * y + z * z); 216 216 217 return (norm < Radius); 217 return (norm < Radius); 218 } 218 } 219 //....oooOO0OOooo........oooOO0OOooo........oo 219 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 220 220 221 G4bool G4DNABoundingBox::contains(const G4Thre 221 G4bool G4DNABoundingBox::contains(const G4ThreeVector& query, 222 const G4doub 222 const G4double& Radius) const 223 { 223 { 224 G4ThreeVector temp = query - this->middlePoi 224 G4ThreeVector temp = query - this->middlePoint(); 225 G4double x = std::abs(temp.x()) + th 225 G4double x = std::abs(temp.x()) + this->halfSideLengthInX(); 226 G4double y = std::abs(temp.y()) + th 226 G4double y = std::abs(temp.y()) + this->halfSideLengthInY(); 227 G4double z = std::abs(temp.z()) + th 227 G4double z = std::abs(temp.z()) + this->halfSideLengthInZ(); 228 G4double norm = std::sqrt(x * x + y * y 228 G4double norm = std::sqrt(x * x + y * y + z * z); 229 return (norm < Radius); 229 return (norm < Radius); 230 } 230 } 231 //....oooOO0OOooo........oooOO0OOooo........oo 231 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 232 232 233 G4bool G4DNABoundingBox::contains(const G4Thre 233 G4bool G4DNABoundingBox::contains(const G4ThreeVector& query, 234 const G4Thre 234 const G4ThreeVector& Point, 235 const G4doub 235 const G4double& Radius) const 236 { 236 { 237 return (((query - Point).mag()) < Radius); 237 return (((query - Point).mag()) < Radius); 238 } 238 } 239 239 240 //....oooOO0OOooo........oooOO0OOooo........oo 240 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 241 241 242 array<G4DNABoundingBox, 8> G4DNABoundingBox::p 242 array<G4DNABoundingBox, 8> G4DNABoundingBox::partition() const 243 { 243 { 244 G4double xmid = (fxhi + fxlo) / 2.; 244 G4double xmid = (fxhi + fxlo) / 2.; 245 G4double ymid = (fyhi + fylo) / 2.; 245 G4double ymid = (fyhi + fylo) / 2.; 246 G4double zmid = (fzhi + fzlo) / 2.; 246 G4double zmid = (fzhi + fzlo) / 2.; 247 247 248 std::array<G4DNABoundingBox, 8> ret{ { 248 std::array<G4DNABoundingBox, 8> ret{ { 249 G4DNABoundingBox{ xmid, fxlo, ymid, fylo, 249 G4DNABoundingBox{ xmid, fxlo, ymid, fylo, zmid, 250 fzlo }, // bottom left 250 fzlo }, // bottom left front 251 G4DNABoundingBox{ fxhi, xmid, ymid, fylo, 251 G4DNABoundingBox{ fxhi, xmid, ymid, fylo, zmid, 252 fzlo }, // bottom right 252 fzlo }, // bottom right front 253 G4DNABoundingBox{ xmid, fxlo, fyhi, ymid, 253 G4DNABoundingBox{ xmid, fxlo, fyhi, ymid, zmid, fzlo }, // bottom left back 254 G4DNABoundingBox{ fxhi, xmid, fyhi, ymid, 254 G4DNABoundingBox{ fxhi, xmid, fyhi, ymid, zmid, 255 fzlo }, // bottom right 255 fzlo }, // bottom right back 256 G4DNABoundingBox{ xmid, fxlo, ymid, fylo, 256 G4DNABoundingBox{ xmid, fxlo, ymid, fylo, fzhi, zmid }, // top left front 257 G4DNABoundingBox{ fxhi, xmid, ymid, fylo, 257 G4DNABoundingBox{ fxhi, xmid, ymid, fylo, fzhi, zmid }, // top right front 258 G4DNABoundingBox{ xmid, fxlo, fyhi, ymid, 258 G4DNABoundingBox{ xmid, fxlo, fyhi, ymid, fzhi, zmid }, // top left back 259 G4DNABoundingBox{ fxhi, xmid, fyhi, ymid, 259 G4DNABoundingBox{ fxhi, xmid, fyhi, ymid, fzhi, zmid } // top right back 260 } }; 260 } }; 261 return ret; 261 return ret; 262 } 262 } 263 //....oooOO0OOooo........oooOO0OOooo........oo 263 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 264 264 265 G4bool G4DNABoundingBox::operator==(const G4DN 265 G4bool G4DNABoundingBox::operator==(const G4DNABoundingBox& rhs) const 266 { 266 { 267 return (fxhi == rhs.fxhi && fxlo == rhs.fxlo 267 return (fxhi == rhs.fxhi && fxlo == rhs.fxlo && fyhi == rhs.fyhi && 268 fylo == rhs.fylo && fzhi == rhs.fzhi 268 fylo == rhs.fylo && fzhi == rhs.fzhi && fzlo == rhs.fzlo) || 269 (std::isnan(fxhi) && std::isnan(rhs.f 269 (std::isnan(fxhi) && std::isnan(rhs.fxhi) && std::isnan(fxlo) && 270 std::isnan(rhs.fxlo) && std::isnan(f 270 std::isnan(rhs.fxlo) && std::isnan(fyhi) && std::isnan(rhs.fyhi) && 271 std::isnan(fylo) && std::isnan(rhs.f 271 std::isnan(fylo) && std::isnan(rhs.fylo) && std::isnan(fzhi) && 272 std::isnan(rhs.fzhi) && std::isnan(f 272 std::isnan(rhs.fzhi) && std::isnan(fzlo) && std::isnan(rhs.fzlo)); 273 } 273 } 274 274 275 G4bool G4DNABoundingBox::operator!=(const G4DN 275 G4bool G4DNABoundingBox::operator!=(const G4DNABoundingBox& rhs) const 276 { 276 { 277 return !operator==(rhs); 277 return !operator==(rhs); 278 } 278 } 279 //....oooOO0OOooo........oooOO0OOooo........oo 279 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 280 280 281 std::ostream& operator<<(std::ostream& stream, 281 std::ostream& operator<<(std::ostream& stream, const G4DNABoundingBox& rhs) 282 { 282 { 283 stream << "{" << G4BestUnit(rhs.fxhi, "Lengt 283 stream << "{" << G4BestUnit(rhs.fxhi, "Length") << ", " 284 << G4BestUnit(rhs.fxlo, "Length") << 284 << G4BestUnit(rhs.fxlo, "Length") << ", " 285 << G4BestUnit(rhs.fyhi, "Length") << 285 << G4BestUnit(rhs.fyhi, "Length") << ", " 286 << G4BestUnit(rhs.fylo, "Length") << 286 << G4BestUnit(rhs.fylo, "Length") << ", " 287 << G4BestUnit(rhs.fzhi, "Length") << 287 << G4BestUnit(rhs.fzhi, "Length") << ", " 288 << G4BestUnit(rhs.fzlo, "Length") << 288 << G4BestUnit(rhs.fzlo, "Length") << ", " 289 << "}"; 289 << "}"; 290 return stream; 290 return stream; 291 } 291 } 292 292