1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "treeBoundBox.H"
29 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
31 inline Foam::treeBoundBox::treeBoundBox()
37 inline Foam::treeBoundBox::treeBoundBox(const point& min, const point& max)
43 inline Foam::treeBoundBox::treeBoundBox(const boundBox& bb)
49 inline Foam::treeBoundBox::treeBoundBox(Istream& is)
55 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
57 inline Foam::scalar Foam::treeBoundBox::typDim() const
63 inline Foam::point Foam::treeBoundBox::corner(const direction octant) const
67 (octant & RIGHTHALF) ? max().x() : min().x(),
68 (octant & TOPHALF) ? max().y() : min().y(),
69 (octant & FRONTHALF) ? max().z() : min().z()
74 // Returns octant in which point resides. Reverse of subBbox.
75 inline Foam::direction Foam::treeBoundBox::subOctant(const point& pt) const
77 return subOctant(midpoint(), pt);
81 // Returns octant in which point resides. Reverse of subBbox.
82 // Precalculated midpoint
83 inline Foam::direction Foam::treeBoundBox::subOctant
93 octant |= treeBoundBox::RIGHTHALF;
98 octant |= treeBoundBox::TOPHALF;
101 if (pt.z() > mid.z())
103 octant |= treeBoundBox::FRONTHALF;
110 // Returns octant in which point resides. Reverse of subBbox.
111 // Flags point exactly on edge.
112 inline Foam::direction Foam::treeBoundBox::subOctant
118 return subOctant(midpoint(), pt, onEdge);
122 // Returns octant in which point resides. Reverse of subBbox.
123 // Precalculated midpoint
124 inline Foam::direction Foam::treeBoundBox::subOctant
131 direction octant = 0;
134 if (pt.x() > mid.x())
136 octant |= treeBoundBox::RIGHTHALF;
138 else if (pt.x() == mid.x())
143 if (pt.y() > mid.y())
145 octant |= treeBoundBox::TOPHALF;
147 else if (pt.y() == mid.y())
152 if (pt.z() > mid.z())
154 octant |= treeBoundBox::FRONTHALF;
156 else if (pt.z() == mid.z())
165 // Returns octant in which intersection resides.
166 // Precalculated midpoint. If the point is on the dividing line between
167 // the octants the direction vector determines which octant to use
168 // (i.e. in which octant the point would be if it were moved along dir)
169 inline Foam::direction Foam::treeBoundBox::subOctant
177 direction octant = 0;
180 if (pt.x() > mid.x())
182 octant |= treeBoundBox::RIGHTHALF;
184 else if (pt.x() == mid.x())
189 octant |= treeBoundBox::RIGHTHALF;
193 if (pt.y() > mid.y())
195 octant |= treeBoundBox::TOPHALF;
197 else if (pt.y() == mid.y())
202 octant |= treeBoundBox::TOPHALF;
206 if (pt.z() > mid.z())
208 octant |= treeBoundBox::FRONTHALF;
210 else if (pt.z() == mid.z())
215 octant |= treeBoundBox::FRONTHALF;
223 // Returns reference to octantOrder which defines the
224 // order to do the search.
225 inline void Foam::treeBoundBox::searchOrder
228 FixedList<direction,8>& octantOrder
231 vector dist = midpoint() - pt;
233 direction octant = 0;
237 octant |= treeBoundBox::RIGHTHALF;
243 octant |= treeBoundBox::TOPHALF;
249 octant |= treeBoundBox::FRONTHALF;
257 if (dist.x() < dist.y())
259 if (dist.y() < dist.z())
261 min = treeBoundBox::RIGHTHALF;
262 mid = treeBoundBox::TOPHALF;
263 max = treeBoundBox::FRONTHALF;
265 else if (dist.z() < dist.x())
267 min = treeBoundBox::FRONTHALF;
268 mid = treeBoundBox::RIGHTHALF;
269 max = treeBoundBox::TOPHALF;
273 min = treeBoundBox::RIGHTHALF;
274 mid = treeBoundBox::FRONTHALF;
275 max = treeBoundBox::TOPHALF;
280 if (dist.z() < dist.y())
282 min = treeBoundBox::FRONTHALF;
283 mid = treeBoundBox::TOPHALF;
284 max = treeBoundBox::RIGHTHALF;
286 else if (dist.x() < dist.z())
288 min = treeBoundBox::TOPHALF;
289 mid = treeBoundBox::RIGHTHALF;
290 max = treeBoundBox::FRONTHALF;
294 min = treeBoundBox::TOPHALF;
295 mid = treeBoundBox::FRONTHALF;
296 max = treeBoundBox::RIGHTHALF;
301 octantOrder[0] = octant;
302 // subOctants joined to the primary by faces.
303 octantOrder[1] = octant ^ min;
304 octantOrder[2] = octant ^ mid;
305 octantOrder[3] = octant ^ max;
306 // subOctants joined to the primary by edges.
307 octantOrder[4] = octantOrder[1] ^ mid;
308 octantOrder[5] = octantOrder[1] ^ max;
309 octantOrder[6] = octantOrder[2] ^ max;
310 // subOctants joined to the primary by corner.
311 octantOrder[7] = octantOrder[4] ^ max;
315 //- Return slightly wider bounding box
316 inline Foam::treeBoundBox Foam::treeBoundBox::extend
322 treeBoundBox bb(*this);
324 vector newSpan = bb.span();
327 scalar minSpan = s * Foam::mag(newSpan);
329 for (direction dir = 0; dir < vector::nComponents; dir++)
331 newSpan[dir] = Foam::max(newSpan[dir], minSpan);
334 bb.min() -= cmptMultiply(s * rndGen.vector01(), newSpan);
335 bb.max() += cmptMultiply(s * rndGen.vector01(), newSpan);
341 // ************************************************************************* //