Branch data Line data Source code
1 : : /***************************************************************************
2 : : qgsbox3d.cpp
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 : : #include "qgsbox3d.h"
19 : : #include "qgspoint.h"
20 : :
21 : 0 : QgsBox3d::QgsBox3d( double xmin, double ymin, double zmin, double xmax, double ymax, double zmax )
22 : 0 : : mBounds2d( xmin, ymin, xmax, ymax )
23 : 0 : , mZmin( zmin )
24 : 0 : , mZmax( zmax )
25 : 0 : {}
26 : :
27 : 0 : QgsBox3d::QgsBox3d( const QgsPoint &p1, const QgsPoint &p2 )
28 : 0 : : mBounds2d( p1.x(), p1.y(), p2.x(), p2.y() )
29 : 0 : , mZmin( std::min( p1.z(), p2.z() ) )
30 : 0 : , mZmax( std::max( p1.z(), p2.z() ) )
31 : : {
32 : 0 : mBounds2d.normalize();
33 : 0 : }
34 : :
35 : 0 : QgsBox3d::QgsBox3d( const QgsRectangle &rect )
36 : 0 : : mBounds2d( rect )
37 : 0 : {}
38 : :
39 : 0 : void QgsBox3d::setXMinimum( double x )
40 : : {
41 : 0 : mBounds2d.setXMinimum( x );
42 : 0 : }
43 : :
44 : 0 : void QgsBox3d::setXMaximum( double x )
45 : : {
46 : 0 : mBounds2d.setXMaximum( x );
47 : 0 : }
48 : :
49 : 0 : void QgsBox3d::setYMinimum( double y )
50 : : {
51 : 0 : mBounds2d.setYMinimum( y );
52 : 0 : }
53 : :
54 : 0 : void QgsBox3d::setYMaximum( double y )
55 : : {
56 : 0 : mBounds2d.setYMaximum( y );
57 : 0 : }
58 : :
59 : 0 : void QgsBox3d::setZMinimum( double z )
60 : : {
61 : 0 : mZmin = z;
62 : 0 : }
63 : :
64 : 0 : void QgsBox3d::setZMaximum( double z )
65 : : {
66 : 0 : mZmax = z;
67 : 0 : }
68 : :
69 : 0 : void QgsBox3d::normalize()
70 : : {
71 : 0 : mBounds2d.normalize();
72 : 0 : double z1 = std::min( mZmin, mZmax );
73 : 0 : double z2 = std::max( mZmin, mZmax );
74 : 0 : mZmin = z1;
75 : 0 : mZmax = z2;
76 : 0 : }
77 : :
78 : 0 : QgsBox3d QgsBox3d::intersect( const QgsBox3d &other ) const
79 : : {
80 : 0 : QgsRectangle intersect2d = mBounds2d.intersect( other.mBounds2d );
81 : 0 : double zMin = std::max( mZmin, other.mZmin );
82 : 0 : double zMax = std::min( mZmax, other.mZmax );
83 : 0 : return QgsBox3d( intersect2d.xMinimum(), intersect2d.yMinimum(), zMin,
84 : 0 : intersect2d.xMaximum(), intersect2d.yMaximum(), zMax );
85 : : }
86 : :
87 : 0 : bool QgsBox3d::is2d() const
88 : : {
89 : 0 : return qgsDoubleNear( mZmin, mZmax ) || ( mZmin > mZmax );
90 : : }
91 : :
92 : 0 : bool QgsBox3d::intersects( const QgsBox3d &other ) const
93 : : {
94 : 0 : if ( !mBounds2d.intersects( other.mBounds2d ) )
95 : 0 : return false;
96 : :
97 : 0 : double z1 = ( mZmin > other.mZmin ? mZmin : other.mZmin );
98 : 0 : double z2 = ( mZmax < other.mZmax ? mZmax : other.mZmax );
99 : 0 : return z1 <= z2;
100 : 0 : }
101 : :
102 : 0 : bool QgsBox3d::contains( const QgsBox3d &other ) const
103 : : {
104 : 0 : if ( !mBounds2d.contains( other.mBounds2d ) )
105 : 0 : return false;
106 : :
107 : 0 : return ( other.mZmin >= mZmin && other.mZmax <= mZmax );
108 : 0 : }
109 : :
110 : 0 : bool QgsBox3d::contains( const QgsPoint &p ) const
111 : : {
112 : 0 : if ( !mBounds2d.contains( p.x(), p.y() ) )
113 : 0 : return false;
114 : :
115 : 0 : if ( p.is3D() )
116 : 0 : return mZmin <= p.z() && p.z() <= mZmax;
117 : : else
118 : 0 : return true;
119 : 0 : }
120 : :
121 : 0 : double QgsBox3d::distanceTo( const QVector3D &point ) const
122 : : {
123 : 0 : double dx = std::max( mBounds2d.xMinimum() - point.x(), std::max( 0., point.x() - mBounds2d.xMaximum() ) );
124 : 0 : double dy = std::max( mBounds2d.yMinimum() - point.y(), std::max( 0., point.y() - mBounds2d.yMaximum() ) );
125 : 0 : double dz = std::max( mZmin - point.z(), std::max( 0., point.z() - mZmax ) );
126 : 0 : return sqrt( dx * dx + dy * dy + dz * dz );
127 : : }
128 : :
129 : :
130 : 0 : bool QgsBox3d::operator==( const QgsBox3d &other ) const
131 : : {
132 : 0 : return mBounds2d == other.mBounds2d &&
133 : 0 : qgsDoubleNear( mZmin, other.mZmin ) &&
134 : 0 : qgsDoubleNear( mZmax, other.mZmax );
135 : : }
|