Seg3D  2.4
Seg3D is a free volume segmentation and processing tool developed by the NIH Center for Integrative Biomedical Computing at the University of Utah Scientific Computing and Imaging (SCI) Institute.
the_aa_bbox.hxx
1 /*
2  For more information, please see: http://software.sci.utah.edu
3 
4  The MIT License
5 
6  Copyright (c) 2016 Scientific Computing and Imaging Institute,
7  University of Utah.
8 
9 
10  Permission is hereby granted, free of charge, to any person obtaining a
11  copy of this software and associated documentation files (the "Software"),
12  to deal in the Software without restriction, including without limitation
13  the rights to use, copy, modify, merge, publish, distribute, sublicense,
14  and/or sell copies of the Software, and to permit persons to whom the
15  Software is furnished to do so, subject to the following conditions:
16 
17  The above copyright notice and this permission notice shall be included
18  in all copies or substantial portions of the Software.
19 
20  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26  DEALINGS IN THE SOFTWARE.
27  */
28 
29 // File : the_aa_bbox.hxx
30 // Author : Pavel A. Koshevoy
31 // Created : Mon Jun 7 22:14:00 MDT 2004
32 // Copyright : (C) 2004-2008 University of Utah
33 // Description : Axis aligned 3D bounding box.
34 
35 #ifndef THE_AA_BBOX_HXX_
36 #define THE_AA_BBOX_HXX_
37 
38 // system includes:
39 #include <iostream>
40 
41 // local includes:
42 #include <Core/ITKCommon/v3x1p3x1.hxx>
43 
44 // namespace access:
45 using std::ostream;
46 
47 
48 // axis aligned bounding box layout:
49 //
50 // C1-------E9------C5
51 // /| /|
52 // / | / | Z = [0 0 1]T
53 // E0 | F0 E4 | |
54 // / e1 f1 / | |
55 // / | / E5 | reference coordinate system
56 // C0-------E8------C4 | |
57 // | | | F5 | + - - - - Y = [0 1 0]T
58 // | f4 c2----e10-|-----C6 /
59 // | / | / /
60 // E3 / F3 E7 / X = [1 0 0]T
61 // | e2 f2 | E6
62 // | / | /
63 // |/ |/
64 // C3------E11------C7
65 //
66 // Fi - face id, fi - hidden face id.
67 // Ei - edge id, ei - hidden edge id.
68 // Ci - corner id, ci - hidden corner id.
69 //
70 // The bounding box faces correspond to the fiew point orientation as follows:
71 // F0 = top face
72 // f1 = back face
73 // f2 = bottom face
74 // F3 = front face
75 // f4 = right face
76 // F5 = left face
77 
78 //----------------------------------------------------------------
79 // the_aa_bbox_t
80 //
82 {
83 public:
85  { clear(); }
86 
87  // reset the bounding box to be empty:
88  inline void clear()
89  {
90  min_.assign(FLT_MAX, FLT_MAX, FLT_MAX);
91  max_.assign(-FLT_MAX, -FLT_MAX, -FLT_MAX);
92  }
93 
94  // addition/expansion operators:
95  the_aa_bbox_t & operator << (const p3x1_t & pt);
96  the_aa_bbox_t & operator += (const the_aa_bbox_t & bbox);
97 
98  inline the_aa_bbox_t operator + (const the_aa_bbox_t & bbox) const
99  {
100  the_aa_bbox_t ret_val(*this);
101  return ret_val += bbox;
102  }
103 
104  // scale operators:
105  the_aa_bbox_t & operator *= (const float & s);
106 
107  the_aa_bbox_t operator * (const float & s) const
108  {
109  the_aa_bbox_t result(*this);
110  result *= s;
111  return result;
112  }
113 
114  // uniformly advance/retreat every face of the bounding box by value r:
115  the_aa_bbox_t & operator += (const float & r);
116 
117  inline the_aa_bbox_t operator + (const float & r) const
118  {
119  the_aa_bbox_t result(*this);
120  result += r;
121  return result;
122  }
123 
124  inline the_aa_bbox_t operator - (const float & r) const
125  { return (*this + (-r)); }
126 
127  inline the_aa_bbox_t & operator -= (const float & r)
128  { return (*this += (-r)); }
129 
130  // equality test operator:
131  inline bool operator == (const the_aa_bbox_t & bbox) const
132  { return ((min_ == bbox.min_) && (max_ == bbox.max_)); }
133 
134  inline bool operator != (const the_aa_bbox_t & bbox) const
135  { return !((*this) == bbox); }
136 
137  // return true if the volume of this bounding box is smaller than
138  // the volume of the given bounding box:
139  inline bool operator < (const the_aa_bbox_t & bbox) const
140  { return (volume() < bbox.volume()); }
141 
142  // calculate the volume of this bounding box:
143  inline float volume() const
144  {
145  if (is_empty()) return 0.0;
146  return (max_[0] - min_[0]) * (max_[1] - min_[1]) * (max_[2] - min_[2]);
147  }
148 
149  // convert min/max into 8 bounding box corners,
150  // the caller has to make sure that corner_array is of size 8:
151  void corners(p3x1_t * corner_array) const;
152 
153  // bounding box validity tests:
154  bool is_empty() const;
155 
156  inline bool is_singular() const
157  { return (min_ == max_); }
158 
159  bool is_linear() const;
160  bool is_planar() const;
161  bool is_spacial() const;
162 
163  // calculate the edge length of the bounding box:
164  inline float length(const unsigned int & axis_id) const
165  { return (max_[axis_id] - min_[axis_id]); }
166 
167  // calculate the center of the bounding box:
168  inline p3x1_t center() const
169  { return 0.5f * (max_ + min_); }
170 
171  // calculate the radius of the bounding box (sphere):
172  float radius(const p3x1_t & center) const;
173 
174  inline float radius() const
175  { return 0.5f * diameter(); }
176 
177  inline float diameter() const
178  {
179  if (is_empty()) return 0;
180  return (min_ - max_).norm();
181  }
182 
183  // calculate the radius of the bounding box (cylinder):
184  float radius(const p3x1_t & center, const unsigned int & axis_w_id) const;
185 
186  inline float radius(const unsigned int & axis_w_id) const
187  { return radius(center(), axis_w_id); }
188 
189  // check whether a given point is contained between the faces of the
190  // bounding box normal to the x, y, and z axis - if the point is
191  // contained within all three, the point is inside the bounding box:
192  void contains(const p3x1_t & pt,
193  bool & contained_in_x,
194  bool & contained_in_y,
195  bool & contained_in_z) const;
196 
197  // check whether the bounding box contains a given point:
198  inline bool contains(const p3x1_t & pt) const
199  {
200  bool contained_in_x = false;
201  bool contained_in_y = false;
202  bool contained_in_z = false;
203  contains(pt, contained_in_x, contained_in_y, contained_in_z);
204  return (contained_in_x && contained_in_y && contained_in_z);
205  }
206 
207  // check whether the bounding box contains another bounding box:
208  inline bool contains(const the_aa_bbox_t & bbox) const
209  { return contains(bbox.min_) && contains(bbox.max_); }
210 
211  // check whether the bounding boxes intersect:
212  bool intersects(const the_aa_bbox_t & bbox) const;
213 
214  // clamp this bounding box to lay within the confines of
215  // a given bounding box:
216  void clamp(const the_aa_bbox_t & confines);
217 
218  // return a copy of this bounding box clamped within the given confines:
219  inline the_aa_bbox_t clamped(const the_aa_bbox_t & confines) const
220  {
221  the_aa_bbox_t tmp(*this);
222  tmp.clamp(confines);
223  return tmp;
224  }
225 
226  // find the intersection of this bounding box with a given ray:
227  bool intersects_ray(const p3x1_t & o,
228  const v3x1_t & d,
229  float & t_min,
230  float & t_max) const;
231 
232  // find the axis id of the largest/smallest dimension of the bounding box:
233  unsigned int largest_dimension() const;
234  unsigned int smallest_dimension() const;
235 
236  // For debugging, dumps this bounding box into a stream:
237  void dump(ostream & strm) const;
238 
239  // the minimum and maximum points of the bounding box:
240  p3x1_t min_;
241  p3x1_t max_;
242 };
243 
244 //----------------------------------------------------------------
245 // operator *
246 //
247 inline the_aa_bbox_t
248 operator * (float s, const the_aa_bbox_t & bbox)
249 { return bbox * s; }
250 
251 //----------------------------------------------------------------
252 // operator <<
253 //
254 inline ostream &
255 operator << (ostream & strm, const the_aa_bbox_t & bbox)
256 {
257  bbox.dump(strm);
258  return strm;
259 }
260 
261 
262 #endif // THE_AA_BBOX_HXX_
Definition: v3x1p3x1.hxx:826
Definition: v3x1p3x1.hxx:579
the_aa_bbox_t & operator<<(const p3x1_t &pt)
Definition: the_aa_bbox.cxx:47
Definition: the_aa_bbox.hxx:81