$treeview $search $mathjax
|
Palabos
Version 1.1
$projectbrief
|
$projectbrief
|
$searchbox |
00001 /* This file is part of the Palabos library. 00002 * 00003 * Copyright (C) 2011 FlowKit Sarl 00004 * Avenue de Chailly 23 00005 * 1012 Lausanne, Switzerland 00006 * E-mail contact: contact@flowkit.com 00007 * 00008 * The most recent release of Palabos can be downloaded at 00009 * <http://www.palabos.org/> 00010 * 00011 * The library Palabos is free software: you can redistribute it and/or 00012 * modify it under the terms of the GNU Affero General Public License as 00013 * published by the Free Software Foundation, either version 3 of the 00014 * License, or (at your option) any later version. 00015 * 00016 * The library is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Affero General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU Affero General Public License 00022 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00023 */ 00024 00025 00026 #ifndef GEOMETRY_3D_H 00027 #define GEOMETRY_3D_H 00028 00029 #include "core/globalDefs.h" 00030 #include "core/plbDebug.h" 00031 #include "core/util.h" 00032 #include "core/array.h" 00033 #include "latticeBoltzmann/geometricOperationTemplates.h" 00034 #include <algorithm> 00035 #include <iterator> 00036 #include <vector> 00037 #include <cmath> 00038 00039 namespace plb { 00040 00042 struct Box3D { 00043 Box3D() : x0(), x1(), y0(), y1(), z0(), z1() { } 00044 Box3D(plint x0_, plint x1_, plint y0_, plint y1_, plint z0_, plint z1_) 00045 : x0(x0_), x1(x1_), y0(y0_), y1(y1_), z0(z0_), z1(z1_) 00046 { } 00048 Box3D shift(plint deltaX, plint deltaY, plint deltaZ) const { 00049 return Box3D(x0+deltaX, x1+deltaX, y0+deltaY, y1+deltaY, z0+deltaZ, z1+deltaZ); 00050 } 00052 Box3D multiply(plint scaling) const { 00053 return Box3D(scaling*x0, scaling*x1, scaling*y0, 00054 scaling*y1, scaling*z0, scaling*z1); 00055 } 00057 Box3D divide(plint scaling) const { 00058 return Box3D(x0/scaling, x1/scaling, y0/scaling, 00059 y1/scaling, z0/scaling, z1/scaling); 00060 } 00062 00070 Box3D divideAndFitSmaller(plint scaling) const { 00071 return Box3D (util::roundUp(x0,scaling)/scaling, util::roundDown(x1,scaling)/scaling, 00072 util::roundUp(y0,scaling)/scaling, util::roundDown(y1,scaling)/scaling, 00073 util::roundUp(z0,scaling)/scaling, util::roundDown(z1,scaling)/scaling); 00074 } 00075 00077 00085 Box3D divideAndFitLarger(plint scaling) const { 00086 return Box3D (util::roundDown(x0,scaling)/scaling, util::roundUp(x1,scaling)/scaling, 00087 util::roundDown(y0,scaling)/scaling, util::roundUp(y1,scaling)/scaling, 00088 util::roundDown(z0,scaling)/scaling, util::roundUp(z1,scaling)/scaling); 00089 } 00090 00092 Box3D enlarge(plint nCells) const { 00093 return Box3D(x0-nCells, x1+nCells, y0-nCells, y1+nCells, z0-nCells, z1+nCells); 00094 } 00096 plint getNx() const { return (x1-x0+1); } 00098 plint getNy() const { return (y1-y0+1); } 00100 plint getNz() const { return (z1-z0+1); } 00102 plint nCells() const { return getNx()*getNy()*getNz(); } 00104 plint getMaxWidth() const { return std::max(std::max(getNx(), getNy()), getNz()); } 00106 Array<plint,6> to_plbArray() const { 00107 Array<plint,6> array; 00108 array[0] = x0; array[1] = x1; 00109 array[2] = y0; array[3] = y1; 00110 array[4] = z0; array[5] = z1; 00111 return array; 00112 } 00114 void from_plbArray(Array<plint,6> const& array) { 00115 x0 = array[0]; x1 = array[1]; 00116 y0 = array[2]; y1 = array[3]; 00117 z0 = array[4]; z1 = array[5]; 00118 } 00119 00120 bool operator==(Box3D const& rhs) { 00121 return x0 == rhs.x0 && y0 == rhs.y0 && z0 == rhs.z0 && 00122 x1 == rhs.x1 && y1 == rhs.y1 && z1 == rhs.z1; 00123 } 00124 00125 plint x0, x1, y0, y1, z0, z1; 00126 }; 00127 00129 struct Dot3D { 00130 Dot3D() : x(), y(), z() { } 00131 Dot3D(plint x_, plint y_, plint z_) : x(x_), y(y_), z(z_) { } 00132 Dot3D& operator+=(Dot3D const& rhs) { 00133 x += rhs.x; 00134 y += rhs.y; 00135 z += rhs.z; 00136 return *this; 00137 } 00138 Dot3D& operator-=(Dot3D const& rhs) { 00139 x -= rhs.x; 00140 y -= rhs.y; 00141 z -= rhs.z; 00142 return *this; 00143 } 00144 00145 template<typename T> 00146 Array<T,3> to_plbArray() const { return Array<T,3>((T)x,(T)y,(T)z); } 00147 00148 plint x, y, z; 00149 }; 00150 00151 inline Dot3D operator+(Dot3D const& dot1, Dot3D const& dot2) { 00152 return Dot3D(dot1) += dot2; 00153 } 00154 00155 inline Dot3D operator-(Dot3D const& dot1, Dot3D const& dot2) { 00156 return Dot3D(dot1) -= dot2; 00157 } 00158 00160 inline bool operator<(Dot3D const& dot1, Dot3D const& dot2) { 00161 return (dot1.x < dot2.x) || ( 00162 (dot1.x == dot2.x) && ( 00163 (dot1.y < dot2.y) || ( 00164 (dot1.y == dot2.y) && (dot1.z < dot2.z) ) ) ); 00165 } 00166 00167 inline bool operator==(Dot3D const& dot1, Dot3D const& dot2) { 00168 return (dot1.x == dot2.x) && (dot1.y == dot2.y) && 00169 (dot1.z == dot2.z); 00170 } 00171 00174 inline bool operator<(Box3D const& box1, Box3D const& box2) { 00175 return ( Dot3D(box1.x0,box1.y0,box1.z0) < Dot3D(box2.x0,box2.y0,box2.z0) ) || ( 00176 ( Dot3D(box1.x0,box1.y0,box1.z0) == Dot3D(box2.x0,box2.y0,box2.z0) ) && 00177 ( Dot3D(box1.x1,box1.y1,box1.z1) < Dot3D(box2.x1,box2.y1,box2.z1) ) ); 00178 } 00179 00181 struct DotList3D { 00182 DotList3D() { } 00183 DotList3D(std::vector<Dot3D> const& dots_) : dots(dots_) { } 00185 void addDot(Dot3D dot) { 00186 dots.push_back(dot); 00187 } 00189 void addDots(std::vector<Dot3D> const& dots_) { 00190 dots.insert(dots.end(), dots_.begin(), dots_.end()); 00191 } 00193 Dot3D const& getDot(plint whichDot) const { 00194 PLB_PRECONDITION( whichDot<getN() ); 00195 return dots[whichDot]; 00196 } 00198 Dot3D& getDot(plint whichDot) { 00199 PLB_PRECONDITION( whichDot<getN() ); 00200 return dots[whichDot]; 00201 } 00203 DotList3D shift(plint deltaX, plint deltaY, plint deltaZ) const { 00204 std::vector<Dot3D> newDots; 00205 std::vector<Dot3D>::const_iterator it = dots.begin(); 00206 for (; it!=dots.end(); ++it) { 00207 newDots.push_back( Dot3D(it->x+deltaX, it->y+deltaY, it->z+deltaZ) ); 00208 } 00209 return DotList3D(newDots); 00210 } 00212 DotList3D multiply(plint scaling) const { 00213 std::vector<Dot3D> newDots; 00214 std::vector<Dot3D>::const_iterator it = dots.begin(); 00215 for (; it!=dots.end(); ++it) { 00216 newDots.push_back( Dot3D(it->x*scaling, it->y*scaling, it->z*scaling) ); 00217 } 00218 return DotList3D(newDots); 00219 } 00221 DotList3D divide(plint scaling) const { 00222 std::vector<Dot3D> newDots; 00223 std::vector<Dot3D>::const_iterator it = dots.begin(); 00224 for (; it!=dots.end(); ++it) { 00225 newDots.push_back( Dot3D(it->x/scaling, it->y/scaling, it->z/scaling) ); 00226 } 00227 return DotList3D(newDots); 00228 00229 } 00231 plint getN() const { 00232 return dots.size(); 00233 } 00234 00235 std::vector<Dot3D> dots; 00236 }; 00237 00239 inline bool contained(plint x, plint y, plint z, Box3D const& box) { 00240 return x>=box.x0 && x<=box.x1 && 00241 y>=box.y0 && y<=box.y1 && 00242 z>=box.z0 && z<=box.z1; 00243 } 00244 00246 inline bool contained(Dot3D dot, Box3D const& box) { 00247 return contained(dot.x, dot.y, dot.z, box); 00248 } 00249 00251 inline bool contained(Box3D const& box1, Box3D const& box2) { 00252 return box1.x0>=box2.x0 && box1.x1<=box2.x1 && 00253 box1.y0>=box2.y0 && box1.y1<=box2.y1 && 00254 box1.z0>=box2.z0 && box1.z1<=box2.z1; 00255 } 00256 00258 00260 inline bool intersect(Box3D const& box1, Box3D const& box2, Box3D& inters) { 00261 inters.x0 = std::max(box1.x0,box2.x0); 00262 inters.y0 = std::max(box1.y0,box2.y0); 00263 inters.z0 = std::max(box1.z0,box2.z0); 00264 00265 inters.x1 = std::min(box1.x1,box2.x1); 00266 inters.y1 = std::min(box1.y1,box2.y1); 00267 inters.z1 = std::min(box1.z1,box2.z1); 00268 00269 return inters.x1>=inters.x0 && inters.y1>=inters.y0 && inters.z1>=inters.z0; 00270 } 00271 00273 inline bool doesIntersect(Box3D const& box1, Box3D const& box2) { 00274 return (std::min(box1.x1,box2.x1) >= std::max(box1.x0,box2.x0)) && 00275 (std::min(box1.y1,box2.y1) >= std::max(box1.y0,box2.y0)) && 00276 (std::min(box1.z1,box2.z1) >= std::max(box1.z0,box2.z0)); 00277 } 00278 00281 inline bool merge(Box3D& box1, Box3D const& box2) { 00282 if (box1.x0==box2.x0 && box1.x1==box2.x1 && 00283 box1.y0==box2.y0 && box1.y1==box2.y1) { 00284 if (box2.z0==box1.z1+1) { 00285 box1.z1=box2.z1; 00286 return true; 00287 } 00288 if (box2.z1+1==box1.z0) { 00289 box1.z0=box2.z0; 00290 return true; 00291 } 00292 } 00293 if (box1.x0==box2.x0 && box1.x1==box2.x1 && 00294 box1.z0==box2.z0 && box1.z1==box2.z1) { 00295 if (box2.y0==box1.y1+1) { 00296 box1.y1=box2.y1; 00297 return true; 00298 } 00299 if (box2.y1+1==box1.y0) { 00300 box1.y0=box2.y0; 00301 return true; 00302 } 00303 } 00304 if (box1.y0==box2.y0 && box1.y1==box2.y1 && 00305 box1.z0==box2.z0 && box1.z1==box2.z1) { 00306 if (box2.x0==box1.x1+1) { 00307 box1.x1=box2.x1; 00308 return true; 00309 } 00310 if (box2.x1+1==box1.x0) { 00311 box1.x0=box2.x0; 00312 return true; 00313 } 00314 } 00315 return false; 00316 } 00317 00319 00321 inline bool intersect(Box3D const& box, DotList3D const& dotlist, DotList3D& inters) { 00322 inters = DotList3D(); 00323 std::vector<Dot3D>::const_iterator it = dotlist.dots.begin(); 00324 for (; it != dotlist.dots.end(); ++it) { 00325 if ( contained(it->x,it->y,it->z, box) ) { 00326 inters.addDot(*it); 00327 } 00328 } 00329 return !inters.dots.empty(); 00330 } 00331 00333 00335 inline void except(Box3D const& originalBox, Box3D const& toExcept, std::vector<Box3D>& result) 00336 { 00337 Box3D intersection; 00338 bool doesIntersect = intersect(originalBox, toExcept, intersection); 00339 if (!doesIntersect) { 00340 result.push_back(originalBox); 00341 } 00342 else { 00343 if (intersection.x0 != originalBox.x0) { 00344 result.push_back(Box3D(originalBox.x0, intersection.x0-1, originalBox.y0, originalBox.y1, originalBox.z0, originalBox.z1)); 00345 } 00346 if (intersection.x1 != originalBox.x1) { 00347 result.push_back(Box3D(intersection.x1+1, originalBox.x1, originalBox.y0, originalBox.y1, originalBox.z0, originalBox.z1)); 00348 } 00349 if (intersection.y0 != originalBox.y0) { 00350 result.push_back(Box3D(intersection.x0, intersection.x1, originalBox.y0, intersection.y0-1, originalBox.z0, originalBox.z1)); 00351 } 00352 if (intersection.y1 != originalBox.y1) { 00353 result.push_back(Box3D(intersection.x0, intersection.x1, intersection.y1+1, originalBox.y1, originalBox.z0, originalBox.z1)); 00354 } 00355 if (intersection.z0 != originalBox.z0) { 00356 result.push_back(Box3D(intersection.x0, intersection.x1, intersection.y0, intersection.y1, originalBox.z0, intersection.z0-1)); 00357 } 00358 if (intersection.z1 != originalBox.z1) { 00359 result.push_back(Box3D(intersection.x0, intersection.x1, intersection.y0, intersection.y1, intersection.z1+1, originalBox.z1)); 00360 } 00361 } 00362 } 00363 00364 00366 inline Box3D bound(Box3D const& box1, Box3D const& box2) { 00367 return Box3D ( 00368 std::min(box1.x0, box2.x0), std::max(box1.x1, box2.x1), 00369 std::min(box1.y0, box2.y0), std::max(box1.y1, box2.y1), 00370 std::min(box1.z0, box2.z0), std::max(box1.z1, box2.z1) ); 00371 } 00372 00374 inline void adjustEqualSize(Box3D& fromDomain, Box3D& toDomain) 00375 { 00376 plint deltaX = fromDomain.x0 - toDomain.x0; 00377 plint deltaY = fromDomain.y0 - toDomain.y0; 00378 plint deltaZ = fromDomain.z0 - toDomain.z0; 00379 Box3D intersection; 00380 intersect(fromDomain, toDomain.shift(deltaX,deltaY,deltaZ), intersection); 00381 fromDomain = intersection; 00382 toDomain = intersection.shift(-deltaX,-deltaY,-deltaZ); 00383 } 00384 00386 template<typename T> 00387 struct Plane { 00388 Array<T,3> point; 00389 Array<T,3> normal; 00390 }; 00391 00393 template<typename T> 00394 struct Cuboid { 00395 Array<T,3> lowerLeftCorner; 00396 Array<T,3> upperRightCorner; 00397 }; 00398 00406 template<typename T> 00407 inline int lineIntersectionWithPlane ( 00408 Plane<T> const& plane, Array<T,3> const& point1, 00409 Array<T,3> const& point2, Precision precision, Array<T,3>& intersection ) 00410 { 00411 T epsilon = getEpsilon<T>(precision); 00412 00413 Array<T,3> direction = point2 - point1; 00414 00415 T num = dot(plane.point, plane.normal) - dot(point1, plane.normal); 00416 T denom = dot(direction, plane.normal); 00417 00418 if (fabs(denom) <= epsilon) { 00419 return -1; // Line belongs to the plane or does not intersect it. 00420 } 00421 00422 T t = num / denom; 00423 00424 if ((t < 0.0 && !(fabs(t) <= epsilon)) || 00425 (t > 1.0 && !(fabs(t - 1.0) <= epsilon))) { 00426 return 0; 00427 } 00428 00429 intersection = point1 + direction * t; // Intersection point with the plane. 00430 00431 return 1; 00432 } 00433 } // namespace plb 00434 00435 #endif // GEOMETRY_3D_H
1.6.3
1.6.3