1 #if !defined  HAVE_BOUNDING_BOX_3D_H__
2 #define       HAVE_BOUNDING_BOX_3D_H__
3 // This file is part of the FXT library.
4 // Copyright (C) 2019, 2021 Joerg Arndt
5 // License: GNU General Public License version 3 or later,
6 // see the file COPYING.txt in the main directory.
7 
8 
9 #include "ds/point3d.h"
10 #include "ds/vector3d.h"
11 
12 #include <iostream>
13 
14 
15 template <typename Type>
16 class bounding_box_3d
17 // 3-dimensional bounding box that can grow to contain
18 // coordinates given in the update() method.
19 {
20 public:
21     typedef point3d<Type> Pnt;
22 
23 protected:
24     Type ix_, ax_;  // min-x, max-x
25     Type iy_, ay_;  // min-y, max-y
26     Type iz_, az_;  // min-z, max-z
27 
28 public:
reset(const Pnt & P)29     void reset( const Pnt & P )
30     {
31         ix_ = P.x();  ax_ = P.x();
32         iy_ = P.y();  ay_ = P.y();
33         iz_ = P.z();  az_ = P.z();
34     }
35 
bounding_box_3d(const Pnt & P)36     explicit bounding_box_3d( const Pnt & P )
37     { reset( P ); }
38 
bounding_box_3d(const Pnt & P,const Pnt & Q)39     explicit bounding_box_3d( const Pnt & P, const Pnt & Q )
40     { reset( P );  update( Q ); }
41 
update(const Pnt & P)42     void update( const Pnt & P )
43     // Enlarge bounding_box_3d to contain P if needed.
44     {
45         Type x = P.x(), y = P.y(), z = P.z();
46         if ( x < ix_ )  ix_ = x;
47         if ( x > ax_ )  ax_ = x;
48         if ( y < iy_ )  iy_ = y;
49         if ( y > ay_ )  ay_ = y;
50         if ( z < iz_ )  iz_ = z;
51         if ( z > az_ )  az_ = z;
52     }
53 
delta_x()54     Type delta_x()  const  { return ax_ - ix_; }  // width
delta_y()55     Type delta_y()  const  { return ay_ - iy_; }  // height
delta_z()56     Type delta_z()  const  { return az_ - iz_; }  // depth
57 
min_x()58     Type min_x()  const  { return ix_; }
min_y()59     Type min_y()  const  { return iy_; }
min_z()60     Type min_z()  const  { return iz_; }
max_x()61     Type max_x()  const  { return ax_; }
max_y()62     Type max_y()  const  { return ay_; }
max_z()63     Type max_z()  const  { return az_; }
64 
min_point()65     Pnt min_point()  const  { return Pnt( ix_, iy_, iz_ ); }
max_point()66     Pnt max_point()  const  { return Pnt( ax_, ay_, az_ ); }
67 
mid_point()68     Pnt mid_point()  const
69     {
70         const Pnt Pi = min_point(),  Pa = max_point();
71         return ::mid_point( Pi, Pa );
72     }
73 
extent()74     Type extent()  const
75     {
76         return vector2d<Type>( max_point() - min_point() );
77     }
78 
inside_q(const Pnt & P)79     bool inside_q( const Pnt & P )  const
80     {
81         if ( ix_ > P.x() )  return false;
82         if ( iy_ > P.y() )  return false;
83         if ( iz_ > P.z() )  return false;
84         if ( ax_ < P.x() )  return false;
85         if ( ay_ < P.y() )  return false;
86         if ( az_ < P.z() )  return false;
87         return true;
88     }
89 
outside_q(const Pnt & P)90     bool outside_q( const Pnt & P )  const  { return ( ! inside_q( P ) ); }
91 };
92 // -------------------------
93 
94 
95 template <typename Type>
96 inline std::ostream & operator << (std::ostream & os, const bounding_box_3d<Type> &B)
97 {
98     os << " BB[" << B.min_point() << " , " << B.max_point() << "]";
99     return os;
100 }
101 // -------------------------
102 
103 
104 #endif // !defined HAVE_BOUNDING_BOX_3D_H__
105