1 /*************************************************************************** 2 qgsellipse.h 3 -------------- 4 begin : March 2017 5 copyright : (C) 2017 by Loîc Bartoletti 6 email : lbartoletti at tuxfamily dot org 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 QGSELLIPSE_H 19 #define QGSELLIPSE_H 20 21 #include <QString> 22 23 #include "qgis_core.h" 24 #include "qgspoint.h" 25 #include "qgspolygon.h" 26 #include "qgslinestring.h" 27 #include "qgsrectangle.h" 28 29 /** 30 * \ingroup core 31 * \class QgsEllipse 32 * \brief Ellipse geometry type. 33 * 34 * An ellipse is defined by a center point with a semi-major axis, a semi-minor axis and an azimuth. 35 * The azimuth is the north angle to the first quadrant (always oriented on the semi-major axis), in degrees. By default, the semi-major axis is oriented to the east (90 degrees). 36 * The semi-minor axis is always smaller than the semi-major axis. If it is set larger, it will be swapped and the azimuth will increase by 90 degrees. 37 * \since QGIS 3.0 38 */ 39 class CORE_EXPORT QgsEllipse 40 { 41 42 public: 43 44 /** 45 * Constructor for QgsEllipse. 46 */ 47 QgsEllipse() SIP_HOLDGIL = default; 48 49 virtual ~QgsEllipse() = default; 50 51 /** 52 * Constructs an ellipse by defining all the members. 53 * \param center The center of the ellipse. 54 * \param semiMajorAxis Semi-major axis of the ellipse. 55 * \param semiMinorAxis Semi-minor axis of the ellipse. 56 * \param azimuth Angle in degrees started from the North to the first quadrant. 57 */ 58 QgsEllipse( const QgsPoint ¢er, double semiMajorAxis, double semiMinorAxis, double azimuth = 90 ) SIP_HOLDGIL; 59 60 /** 61 * Constructs an ellipse by foci (\a pt1 and \a pt2) and a point \a pt3. 62 * The center point can have m value which is the result from the midpoint 63 * operation between \a pt1 and \a pt2. Z dimension is also supported and 64 * is retrieved from the first 3D point amongst \a pt1 and \a pt2. 65 * Axes are calculated from the 2D distance with the third point \a pt3. 66 * The azimuth is the angle between \a pt1 and \a pt2. 67 * \param pt1 First focus. 68 * \param pt2 Second focus. 69 * \param pt3 A point to calculate the axes. 70 */ 71 static QgsEllipse fromFoci( const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3 ) SIP_HOLDGIL; 72 73 /** 74 * Constructs an ellipse by an extent (aka bounding box / QgsRectangle). 75 * The center point can have m value which is the result from the midpoint 76 * operation between \a pt1 and \a pt2. Z dimension is also supported and 77 * is retrieved from the first 3D point amongst \a pt1 and \a pt2. 78 * Axes are calculated from the 2D distance between \a pt1 and \a pt2. 79 * The azimuth always takes the default value. 80 * \param pt1 First corner. 81 * \param pt2 Second corner. 82 */ 83 static QgsEllipse fromExtent( const QgsPoint &pt1, const QgsPoint &pt2 ) SIP_HOLDGIL; 84 85 /** 86 * Constructs an ellipse by a center point and a another point. 87 * The center point keeps m value from \a ptc. Z dimension is also 88 * supported and is retrieved from the first 3D point amongst \a ptc and 89 * \a pt1. 90 * Axes are calculated from the 2D distance between \a ptc and \a pt1. 91 * The azimuth always takes the default value. 92 * \param ptc Center point. 93 * \param pt1 First point. 94 */ 95 static QgsEllipse fromCenterPoint( const QgsPoint &ptc, const QgsPoint &pt1 ) SIP_HOLDGIL; 96 97 /** 98 * Constructs an ellipse by a central point and two other points. 99 * The center point keeps m value from \a ptc. Z dimension is also 100 * supported and is retrieved from the first 3D point amongst \a ptc, 101 * \a pt1 and \a pt2. 102 * Axes are calculated from the 2D distance between \a ptc and \a pt1 and \a pt2. 103 * The azimuth is the angle between \a ptc and \a pt1. 104 * \param ptc Center point. 105 * \param pt1 First point. 106 * \param pt2 Second point. 107 */ 108 static QgsEllipse fromCenter2Points( const QgsPoint &ptc, const QgsPoint &pt1, const QgsPoint &pt2 ) SIP_HOLDGIL; 109 110 virtual bool operator ==( const QgsEllipse &elp ) const; 111 virtual bool operator !=( const QgsEllipse &elp ) const; 112 113 //! An ellipse is empty if axes are equal to 0 114 virtual bool isEmpty() const SIP_HOLDGIL; 115 116 /** 117 * Returns the center point. 118 * \see setCenter() 119 * \see rcenter() 120 */ center()121 QgsPoint center() const SIP_HOLDGIL {return mCenter; } 122 123 /** 124 * Returns the semi-major axis. 125 * \see setSemiMajorAxis() 126 */ semiMajorAxis()127 double semiMajorAxis() const SIP_HOLDGIL {return mSemiMajorAxis; } 128 129 /** 130 * Returns the semi-minor axis. 131 * \see setSemiMinorAxis() 132 */ semiMinorAxis()133 double semiMinorAxis() const SIP_HOLDGIL {return mSemiMinorAxis; } 134 135 /** 136 * Returns the azimuth. 137 * \see setAzimuth() 138 */ azimuth()139 double azimuth() const SIP_HOLDGIL {return mAzimuth; } 140 141 /** 142 * Returns a reference to the center point of this ellipse. 143 * Using a reference makes it possible to directly manipulate center in place. 144 * \see center() 145 * \see setCenter() 146 * \note not available in Python bindings 147 */ rcenter()148 QgsPoint &rcenter() SIP_SKIP { return mCenter; } 149 150 /** 151 * Sets the center point. 152 * \see center() 153 * \see rcenter() 154 */ setCenter(const QgsPoint & center)155 void setCenter( const QgsPoint ¢er ) SIP_HOLDGIL {mCenter = center; } 156 157 /** 158 * Sets the semi-major axis. 159 * \see semiMajorAxis() 160 */ 161 virtual void setSemiMajorAxis( double semiMajorAxis ) SIP_HOLDGIL; 162 163 /** 164 * Sets the semi-minor axis. 165 * \see semiMinorAxis() 166 */ 167 virtual void setSemiMinorAxis( double semiMinorAxis ) SIP_HOLDGIL; 168 169 /** 170 * Sets the azimuth (orientation). 171 * \see azimuth() 172 */ 173 void setAzimuth( double azimuth ) SIP_HOLDGIL; 174 175 /** 176 * The distance between the center and each foci. 177 * \see fromFoci() 178 * \see foci() 179 * \return The distance between the center and each foci. 180 */ 181 virtual double focusDistance() const SIP_HOLDGIL; 182 183 /** 184 * Two foci of the ellipse. The axes are oriented by the azimuth and are on the semi-major axis. 185 * \see fromFoci() 186 * \see focusDistance() 187 * \return the two foci. 188 */ 189 virtual QVector<QgsPoint> foci() const; 190 191 /** 192 * The eccentricity of the ellipse. 193 * nan is returned if the ellipse is empty. 194 */ 195 virtual double eccentricity() const SIP_HOLDGIL; 196 //! The area of the ellipse. 197 virtual double area() const SIP_HOLDGIL; 198 //! The circumference of the ellipse using first approximation of Ramanujan. 199 virtual double perimeter() const SIP_HOLDGIL; 200 201 /** 202 * The four quadrants of the ellipse. 203 * They are oriented and started always from semi-major axis. 204 * \return quadrants defined by four points. 205 */ 206 virtual QVector<QgsPoint> quadrant() const; 207 208 /** 209 * Returns a list of points with segmentation from \a segments. 210 * \param segments Number of segments used to segment geometry. 211 */ 212 virtual QgsPointSequence points( unsigned int segments = 36 ) const; 213 214 /** 215 * Returns a segmented polygon. 216 * \param segments Number of segments used to segment geometry. 217 */ 218 virtual QgsPolygon *toPolygon( unsigned int segments = 36 ) const SIP_FACTORY; 219 220 /** 221 * Returns a segmented linestring. 222 * \param segments Number of segments used to segment geometry. 223 */ 224 virtual QgsLineString *toLineString( unsigned int segments = 36 ) const SIP_FACTORY; 225 //virtual QgsCurvePolygon toCurvePolygon() const; 226 227 /** 228 * Returns the oriented minimal bounding box for the ellipse. 229 */ 230 virtual QgsPolygon *orientedBoundingBox() const SIP_FACTORY; 231 232 /** 233 * Returns the minimal bounding box for the ellipse. 234 */ 235 virtual QgsRectangle boundingBox() const; 236 237 /** 238 * returns a string representation of the ellipse. 239 * Members will be truncated to the specified precision. 240 */ 241 virtual QString toString( int pointPrecision = 17, int axisPrecision = 17, int azimuthPrecision = 2 ) const; 242 243 #ifdef SIP_RUN 244 SIP_PYOBJECT __repr__(); 245 % MethodCode 246 QString str = QStringLiteral( "<QgsEllipse: %1>" ).arg( sipCpp->toString() ); 247 sipRes = PyUnicode_FromString( str.toUtf8().constData() ); 248 % End 249 #endif 250 251 protected: 252 QgsPoint mCenter; 253 double mSemiMajorAxis = 0.0; 254 double mSemiMinorAxis = 0.0; 255 double mAzimuth = 90.0; 256 257 private: 258 //! The semi-minor axis is always smaller than the semi-major axis. If it is set larger, it will be swapped and the azimuth will increase by 90 degrees. 259 void normalizeAxis(); 260 }; 261 262 #endif // QGSELLIPSE_H 263