]> SALOME platform Git repositories - tools/medcoupling.git/blob - src/INTERP_KERNEL/BoundingBox.cxx
Salome HOME
Merge from BR_V5_DEV 16Feb09
[tools/medcoupling.git] / src / INTERP_KERNEL / BoundingBox.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D
2 //
3 //  This library is free software; you can redistribute it and/or
4 //  modify it under the terms of the GNU Lesser General Public
5 //  License as published by the Free Software Foundation; either
6 //  version 2.1 of the License.
7 //
8 //  This library is distributed in the hope that it will be useful,
9 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 //  Lesser General Public License for more details.
12 //
13 //  You should have received a copy of the GNU Lesser General Public
14 //  License along with this library; if not, write to the Free Software
15 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 #include "BoundingBox.hxx"
20
21 #include <iostream>
22 #include <algorithm>
23 #include <cassert>
24
25 namespace INTERP_KERNEL
26 {
27   
28   /**
29    * Constructor creating box from an array of the points corresponding
30    * to the vertices of the element.
31    * Each point is represented by an array of three doubles.
32    *
33    * @param pts     array of points 
34    * @param numPts  number of vertices
35    *
36    */
37   BoundingBox::BoundingBox(const double** pts, const unsigned numPts)
38     :_coords(new double[6])
39   {
40     using namespace std;
41     assert(numPts > 1);     
42
43     // initialize with first two points
44     const double* pt1 = pts[0];
45     const double* pt2 = pts[1];
46
47     for(BoxCoord c = XMIN ; c <= ZMIN ; c = BoxCoord(c + 1))
48       {
49         _coords[c] = min(pt1[c], pt2[c]);
50         _coords[c + 3] = max(pt1[c], pt2[c]);
51       }
52
53     for(unsigned i = 2 ; i < numPts ; ++i)
54       {
55         updateWithPoint(pts[i]);
56       }
57   
58     assert(isValid());
59   }
60
61   /**
62    * Constructor creating box from union of two boxes, resulting in a box that encloses both of them
63    *
64    * @param  box1  the first box
65    * @param  box2  the second box
66    */
67   BoundingBox::BoundingBox(const BoundingBox& box1, const BoundingBox& box2) 
68     : _coords(new double[6])
69   {
70     using namespace std;
71     assert(_coords != 0);
72
73     for(BoxCoord c = XMIN ; c <= ZMIN ; c = BoxCoord(c + 1))
74       {
75         _coords[c] = min(box1._coords[c], box2._coords[c]);
76         _coords[c + 3] = max(box1._coords[c + 3], box2._coords[c + 3]);
77       }
78     
79     assert(isValid());
80   }
81
82   /**
83    * Destructor
84    *
85    */
86   BoundingBox::~BoundingBox()
87   {
88     delete[] _coords;
89   }
90
91   /**
92    * Determines if the intersection with a given box is empty
93    * 
94    * @param    box   BoundingBox with which intersection is tested
95    * @return  true if intersection between boxes is empty, false if not
96    */
97   bool BoundingBox::isDisjointWith(const BoundingBox& box) const
98   {
99     for(BoxCoord c = XMIN ; c <= ZMIN ; c = BoxCoord(c + 1))
100       {
101         const double otherMinCoord = box.getCoordinate(c);
102         const double otherMaxCoord = box.getCoordinate(BoxCoord(c + 3));
103        
104         // boxes are disjoint if there exists a direction in which the 
105         // minimum coordinate of one is greater than the maximum coordinate of the other
106
107         // more stable version ?
108         // const double tol = 1.0e-2*_coords[c];
109         // if(_coords[c] > otherMaxCoord + tol 
110         //   || _coords[c + 3] < otherMinCoord - tol)
111        
112        
113         if(_coords[c] > otherMaxCoord 
114            || _coords[c + 3] < otherMinCoord)
115        
116           {
117             return true;
118           }
119        
120       }
121     return false;
122   }
123     
124   
125
126   /**
127    * Updates the bounding box to include a given point
128    * 
129    * @param pt    point to be included
130    *
131    */
132   void BoundingBox::updateWithPoint(const double* pt)
133   {
134     using namespace std;
135
136     for(BoxCoord c = XMIN ; c <= ZMIN ; c = BoxCoord(c + 1))
137       {
138         const double ptVal = pt[c];
139
140         // update min and max coordinates
141         _coords[c] = min(_coords[c], ptVal);
142         _coords[c + 3] = max(_coords[c + 3], ptVal);
143
144       }
145   }
146   
147   /**
148    * Checks if the box is valid, which it is if its minimum coordinates are
149    * smaller than its maximum coordinates in all directions.
150    *
151    * @return  true if the box is valid, false if not
152    */
153   bool BoundingBox::isValid() const
154   {
155     bool valid = true;
156     for(BoxCoord c = XMIN ; c < ZMIN ; c = BoxCoord(c + 1))
157       {
158         if(_coords[c] > _coords[c + 3])
159           {
160             std::cout << "+++ Error in  BoundingBox |: coordinate " << c << " is invalid : "
161                       <<_coords[c] << " > " << _coords[c+3] << std::endl;
162             valid = false;
163           }
164       }
165     return valid;
166   }
167
168 }