1 /*************************************************************************** 2 qgsbox3d.h 3 ---------- 4 begin : April 2017 5 copyright : (C) 2017 by Nyall Dawson 6 email : nyall dot dawson at gmail dot com 7 ***************************************************************************/ 8 9 /*************************************************************************** 10 * * 11 * This program is free software; you can redistribute it and/or modify * 12 * it under the terms of the GNU General Public License as published by * 13 * the Free Software Foundation; either version 2 of the License, or * 14 * (at your option) any later version. * 15 * * 16 ***************************************************************************/ 17 18 #ifndef QGSBOX3D_H 19 #define QGSBOX3D_H 20 21 #include "qgis_core.h" 22 #include "qgsrectangle.h" 23 24 #include <QVector3D> 25 26 class QgsPoint; 27 28 /** 29 * \ingroup core 30 * \brief A 3-dimensional box composed of x, y, z coordinates. 31 * 32 * A box composed of x/y/z minimum and maximum values. It is often used to return the 3D 33 * extent of a geometry or collection of geometries. 34 * 35 * \see QgsRectangle 36 * \since QGIS 3.0 37 */ 38 class CORE_EXPORT QgsBox3d 39 { 40 public: 41 42 /** 43 * Constructor for QgsBox3D which accepts the ranges of x/y/z coordinates. 44 */ 45 QgsBox3d( double xmin = 0, double ymin = 0, double zmin = 0, double xmax = 0, double ymax = 0, double zmax = 0 ) SIP_HOLDGIL; 46 47 /** 48 * Constructs a QgsBox3D from two points representing opposite corners of the box. 49 * The box is normalized after construction. 50 */ 51 QgsBox3d( const QgsPoint &p1, const QgsPoint &p2 ) SIP_HOLDGIL; 52 53 /** 54 * Constructs a QgsBox3D from a rectangle. 55 * Z Minimum and Z Maximum are set to 0.0. 56 */ 57 QgsBox3d( const QgsRectangle &rect ) SIP_HOLDGIL; 58 59 /** 60 * Sets the minimum \a x value. 61 * \see xMinimum() 62 * \see setXMaximum() 63 */ 64 void setXMinimum( double x ) SIP_HOLDGIL; 65 66 /** 67 * Sets the maximum \a x value. 68 * \see xMaximum() 69 * \see setXMinimum() 70 */ 71 void setXMaximum( double x ) SIP_HOLDGIL; 72 73 /** 74 * Returns the minimum x value. 75 * \see setXMinimum() 76 * \see xMaximum() 77 */ xMinimum()78 double xMinimum() const SIP_HOLDGIL { return mBounds2d.xMinimum(); } 79 80 /** 81 * Returns the maximum x value. 82 * \see setXMaximum() 83 * \see xMinimum() 84 */ xMaximum()85 double xMaximum() const SIP_HOLDGIL { return mBounds2d.xMaximum(); } 86 87 /** 88 * Sets the minimum \a y value. 89 * \see yMinimum() 90 * \see setYMaximum() 91 */ 92 void setYMinimum( double y ) SIP_HOLDGIL; 93 94 /** 95 * Sets the maximum \a y value. 96 * \see yMaximum() 97 * \see setYMinimum() 98 */ 99 void setYMaximum( double y ) SIP_HOLDGIL; 100 101 /** 102 * Returns the minimum y value. 103 * \see setYMinimum() 104 * \see yMaximum() 105 */ yMinimum()106 double yMinimum() const SIP_HOLDGIL { return mBounds2d.yMinimum(); } 107 108 /** 109 * Returns the maximum y value. 110 * \see setYMaximum() 111 * \see yMinimum() 112 */ yMaximum()113 double yMaximum() const SIP_HOLDGIL { return mBounds2d.yMaximum(); } 114 115 /** 116 * Sets the minimum \a z value. 117 * \see zMinimum() 118 * \see setZMaximum() 119 */ 120 void setZMinimum( double z ) SIP_HOLDGIL; 121 122 /** 123 * Sets the maximum \a z value. 124 * \see zMaximum() 125 * \see setZMinimum() 126 */ 127 void setZMaximum( double z ) SIP_HOLDGIL; 128 129 /** 130 * Returns the minimum z value. 131 * \see setZMinimum() 132 * \see zMaximum() 133 */ zMinimum()134 double zMinimum() const SIP_HOLDGIL { return mZmin; } 135 136 /** 137 * Returns the maximum z value. 138 * \see setZMaximum() 139 * \see zMinimum() 140 */ zMaximum()141 double zMaximum() const SIP_HOLDGIL { return mZmax; } 142 143 /** 144 * Normalize the box so it has non-negative width/height/depth. 145 */ 146 void normalize(); 147 148 /** 149 * Returns the width of the box. 150 * \see height() 151 * \see depth() 152 */ width()153 double width() const SIP_HOLDGIL { return mBounds2d.width(); } 154 155 /** 156 * Returns the height of the box. 157 * \see width() 158 * \see depth() 159 */ height()160 double height() const SIP_HOLDGIL { return mBounds2d.height(); } 161 162 /** 163 * Returns the depth of the box. 164 * \see width() 165 * \see height() 166 */ depth()167 double depth() const SIP_HOLDGIL { return mZmax - mZmin; } 168 169 /** 170 * Returns the volume of the box. 171 */ volume()172 double volume() const SIP_HOLDGIL { return mBounds2d.area() * ( mZmax - mZmin ); } 173 174 /** 175 * Returns the intersection of this box and another 3D box. 176 */ 177 QgsBox3d intersect( const QgsBox3d &other ) const; 178 179 /** 180 * Returns TRUE if the box can be considered a 2-dimensional box, i.e. 181 * it has equal minimum and maximum z values. 182 */ 183 bool is2d() const SIP_HOLDGIL; 184 185 /** 186 * Returns TRUE if box intersects with another box. 187 */ 188 bool intersects( const QgsBox3d &other ) const; 189 190 /** 191 * Returns TRUE when box contains other box. 192 */ 193 bool contains( const QgsBox3d &other ) const; 194 195 /** 196 * Returns TRUE when box contains a \a point. 197 * 198 * If the point is a 2D point (no z-coordinate), then the containment test 199 * will be performed on the x/y extent of the box only. 200 */ 201 bool contains( const QgsPoint &point ) const; 202 203 /** 204 * Converts the box to a 2D rectangle. 205 */ toRectangle()206 QgsRectangle toRectangle() const { return mBounds2d; } 207 208 /** 209 * Returns the smallest distance between the box and the point \a point 210 * (returns 0 if the point is inside the box) 211 * 212 * \since QGIS 3.18 213 */ 214 double distanceTo( const QVector3D &point ) const; 215 216 bool operator==( const QgsBox3d &other ) const; 217 218 private: 219 220 QgsRectangle mBounds2d; 221 double mZmin = 0.0; 222 double mZmax = 0.0; 223 224 }; 225 226 #endif // QGSBOX3D_H 227