Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgsvector3d.h 3 : : -------------------------------------- 4 : : Date : November 2017 5 : : Copyright : (C) 2017 by Martin Dobias 6 : : Email : wonder dot sk at gmail dot com 7 : : *************************************************************************** 8 : : * * 9 : : * This program is free software; you can redistribute it and/or modify * 10 : : * it under the terms of the GNU General Public License as published by * 11 : : * the Free Software Foundation; either version 2 of the License, or * 12 : : * (at your option) any later version. * 13 : : * * 14 : : ***************************************************************************/ 15 : : 16 : : #ifndef QGSVECTOR3D_H 17 : : #define QGSVECTOR3D_H 18 : : 19 : : #include "qgis_core.h" 20 : : #include "qgis.h" 21 : : 22 : : #include <QVector3D> 23 : : 24 : : /** 25 : : * \ingroup 3d 26 : : * \brief Class for storage of 3D vectors similar to QVector3D, with the difference that it uses double precision 27 : : * instead of single precision floating point numbers. 28 : : * 29 : : * \since QGIS 3.0 30 : : */ 31 : : class CORE_EXPORT QgsVector3D 32 : : { 33 : : public: 34 : : //! Constructs a null vector 35 : 1 : QgsVector3D() = default; 36 : : 37 : : //! Constructs a vector from given coordinates 38 : 183 : QgsVector3D( double x, double y, double z ) 39 : 183 : : mX( x ), mY( y ), mZ( z ) {} 40 : : 41 : : //! Constructs a vector from single-precision QVector3D 42 : : QgsVector3D( const QVector3D &v ) 43 : : : mX( v.x() ), mY( v.y() ), mZ( v.z() ) {} 44 : : 45 : : //! Returns TRUE if all three coordinates are zero 46 : : bool isNull() const { return mX == 0 && mY == 0 && mZ == 0; } 47 : : 48 : : //! Returns X coordinate 49 : 172 : double x() const { return mX; } 50 : : //! Returns Y coordinate 51 : 172 : double y() const { return mY; } 52 : : //! Returns Z coordinate 53 : 202 : double z() const { return mZ; } 54 : : 55 : : //! Sets vector coordinates 56 : 8 : void set( double x, double y, double z ) 57 : : { 58 : 8 : mX = x; 59 : 8 : mY = y; 60 : 8 : mZ = z; 61 : 8 : } 62 : : 63 : 14 : bool operator==( const QgsVector3D &other ) const 64 : : { 65 : 14 : return mX == other.mX && mY == other.mY && mZ == other.mZ; 66 : : } 67 : : bool operator!=( const QgsVector3D &other ) const 68 : : { 69 : : return !operator==( other ); 70 : : } 71 : : 72 : : //! Returns sum of two vectors 73 : 13 : QgsVector3D operator+( const QgsVector3D &other ) const 74 : : { 75 : 13 : return QgsVector3D( mX + other.mX, mY + other.mY, mZ + other.mZ ); 76 : : } 77 : : 78 : : //! Returns difference of two vectors 79 : 38 : QgsVector3D operator-( const QgsVector3D &other ) const 80 : : { 81 : 38 : return QgsVector3D( mX - other.mX, mY - other.mY, mZ - other.mZ ); 82 : : } 83 : : 84 : : //! Returns a new vector multiplied by scalar 85 : 16 : QgsVector3D operator *( const double factor ) const 86 : : { 87 : : 88 : 16 : return QgsVector3D( mX * factor, mY * factor, mZ * factor ); 89 : : } 90 : : 91 : : //! Returns a new vector divided by scalar 92 : 10 : QgsVector3D operator /( const double factor ) const 93 : : { 94 : 10 : return QgsVector3D( mX / factor, mY / factor, mZ / factor ); 95 : : } 96 : : 97 : : //! Returns the dot product of two vectors 98 : 13 : static double dotProduct( const QgsVector3D &v1, const QgsVector3D &v2 ) 99 : : { 100 : 13 : return v1.x() * v2.x() + v1.y() * v2.y() + v1.z() * v2.z(); 101 : : } 102 : : 103 : : //! Returns the cross product of two vectors 104 : 21 : static QgsVector3D crossProduct( const QgsVector3D &v1, const QgsVector3D &v2 ) 105 : : { 106 : 42 : return QgsVector3D( v1.y() * v2.z() - v1.z() * v2.y(), 107 : 21 : v1.z() * v2.x() - v1.x() * v2.z(), 108 : 21 : v1.x() * v2.y() - v1.y() * v2.x() ); 109 : : } 110 : : 111 : : //! Returns the length of the vector 112 : 24 : double length() const 113 : : { 114 : 24 : return sqrt( mX * mX + mY * mY + mZ * mZ ); 115 : : } 116 : : 117 : : //! Normalizes the current vector in place. 118 : 9 : void normalize() 119 : : { 120 : 9 : double len = length(); 121 : 9 : if ( !qgsDoubleNear( len, 0.0 ) ) 122 : : { 123 : 9 : mX /= len; 124 : 9 : mY /= len; 125 : 9 : mZ /= len; 126 : 9 : } 127 : 9 : } 128 : : 129 : : //! Returns the distance with the \a other QgsVector3 130 : 10 : double distance( const QgsVector3D &other ) const 131 : : { 132 : 30 : return std::sqrt( ( mX - other.x() ) * ( mX - other.x() ) + 133 : 20 : ( mY - other.y() ) * ( mY - other.y() ) + 134 : 10 : ( mZ - other.z() ) * ( mZ - other.z() ) ); 135 : : } 136 : : 137 : : //! Returns the perpendicular point of vector \a vp from [\a v1 - \a v2] 138 : 10 : static QgsVector3D perpendicularPoint( const QgsVector3D &v1, const QgsVector3D &v2, const QgsVector3D &vp ) 139 : : { 140 : 10 : QgsVector3D d = ( v2 - v1 ) / v2.distance( v1 ); 141 : 10 : QgsVector3D v = vp - v2; 142 : 10 : double t = dotProduct( v, d ); 143 : 10 : QgsVector3D P = v2 + ( d * t ); 144 : 10 : return P; 145 : : } 146 : : 147 : : /** 148 : : * Returns a string representation of the 3D vector. 149 : : * Members will be truncated to the specified \a precision. 150 : : */ 151 : : QString toString( int precision = 17 ) const 152 : : { 153 : : QString str = "Vector3D ("; 154 : : str += qgsDoubleToString( mX, precision ); 155 : : str += ", "; 156 : : str += qgsDoubleToString( mY, precision ); 157 : : str += ", "; 158 : : str += qgsDoubleToString( mZ, precision ); 159 : : str += ')'; 160 : : return str; 161 : : } 162 : : 163 : : #ifdef SIP_RUN 164 : : SIP_PYOBJECT __repr__(); 165 : : % MethodCode 166 : : QString str = QStringLiteral( "<QgsVector3D: %1>" ).arg( sipCpp->toString() ); 167 : : sipRes = PyUnicode_FromString( str.toUtf8().constData() ); 168 : : % End 169 : : #endif 170 : : private: 171 : 1 : double mX = 0, mY = 0, mZ = 0; 172 : : }; 173 : : 174 : : #endif // QGSVECTOR3D_H