LCOV - code coverage report
Current view: top level - core/geometry - qgscircle.h (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 6 6 100.0 %
Date: 2021-03-26 12:19:53 Functions: 0 0 -
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /***************************************************************************
       2                 :            :                          qgscircle.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 QGSCIRCLE_H
      19                 :            : #define QGSCIRCLE_H
      20                 :            : 
      21                 :            : #include <QString>
      22                 :            : 
      23                 :            : #include "qgis_core.h"
      24                 :            : #include "qgsellipse.h"
      25                 :            : #include "qgspolygon.h"
      26                 :            : #include "qgsrectangle.h"
      27                 :            : #include "qgscircularstring.h"
      28                 :            : 
      29                 :            : 
      30                 :            : class QgsPoint;
      31                 :            : 
      32                 :            : /**
      33                 :            :  * \ingroup core
      34                 :            :  * \class QgsCircle
      35                 :            :  * \brief Circle geometry type.
      36                 :            :  *
      37                 :            :  * A circle is defined by a center point with a radius and an azimuth.
      38                 :            :  * The azimuth is the north angle to the semi-major axis, in degrees. By default, the semi-major axis is oriented to the north (0 degrees).
      39                 :            :  * \since QGIS 3.0
      40                 :            :  */
      41                 :            : 
      42                 :            : 
      43                 :        465 : class CORE_EXPORT QgsCircle : public QgsEllipse
      44                 :            : {
      45                 :            :   public:
      46                 :            :     QgsCircle();
      47                 :            : 
      48                 :            :     /**
      49                 :            :      * Constructs a circle by defining all the members.
      50                 :            :      * \param center The center of the circle.
      51                 :            :      * \param radius The radius of the circle.
      52                 :            :      * \param azimuth Angle in degrees started from the North to the first quadrant.
      53                 :            :      */
      54                 :            :     QgsCircle( const QgsPoint &center, double radius, double azimuth = 0 ) SIP_HOLDGIL;
      55                 :            : 
      56                 :            :     /**
      57                 :            :      * Constructs a circle by 2 points on the circle.
      58                 :            :      * The center point can have m value which is the result from the midpoint
      59                 :            :      * operation between \a pt1 and \a pt2. Z dimension is also supported and
      60                 :            :      * is retrieved from the first 3D point amongst \a pt1 and \a pt2.
      61                 :            :      * The radius is calculated from the 2D distance between \a pt1 and \a pt2.
      62                 :            :      * The azimuth is the angle between \a pt1 and \a pt2.
      63                 :            :      * \param pt1 First point.
      64                 :            :      * \param pt2 Second point.
      65                 :            :      */
      66                 :            :     static QgsCircle from2Points( const QgsPoint &pt1, const QgsPoint &pt2 ) SIP_HOLDGIL;
      67                 :            : 
      68                 :            :     /**
      69                 :            :      * Constructs a circle by 3 points on the circle.
      70                 :            :      * M value is dropped for the center point.
      71                 :            :      * Z dimension is supported and is retrieved from the first 3D point
      72                 :            :      * amongst \a pt1, \a pt2 and \a pt3.
      73                 :            :      * The azimuth always takes the default value.
      74                 :            :      * If the points are colinear an empty circle is returned.
      75                 :            :      * \param pt1 First point.
      76                 :            :      * \param pt2 Second point.
      77                 :            :      * \param pt3 Third point.
      78                 :            :      * \param epsilon Value used to compare point.
      79                 :            :      */
      80                 :            :     static QgsCircle from3Points( const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double epsilon = 1E-8 ) SIP_HOLDGIL;
      81                 :            : 
      82                 :            :     /**
      83                 :            :      * Constructs a circle by a center point and a diameter.
      84                 :            :      * The center point keeps z and m values from \a center.
      85                 :            :      * \param center Center point.
      86                 :            :      * \param diameter Diameter of the circle.
      87                 :            :      * \param azimuth Azimuth of the circle.
      88                 :            :      */
      89                 :            :     static QgsCircle fromCenterDiameter( const QgsPoint &center, double diameter, double azimuth = 0 ) SIP_HOLDGIL;
      90                 :            : 
      91                 :            : 
      92                 :            :     /**
      93                 :            :      * Constructs a circle by a center point and another point.
      94                 :            :      * The center point keeps z and m values from \a center.
      95                 :            :      * Axes are calculated from the 2D distance between \a center and \a pt1.
      96                 :            :      * The azimuth is the angle between \a center and \a pt1.
      97                 :            :      * \param center Center point.
      98                 :            :      * \param pt1 A point on the circle.
      99                 :            :      */
     100                 :            :     static QgsCircle fromCenterPoint( const QgsPoint &center, const QgsPoint &pt1 ) SIP_HOLDGIL;
     101                 :            : 
     102                 :            : 
     103                 :            :     /**
     104                 :            :      * Constructs a circle by 3 tangents on the circle (aka inscribed circle of a triangle).
     105                 :            :      * Z and m values are dropped for the center point.
     106                 :            :      * The azimuth always takes the default value.
     107                 :            :      * \param pt1_tg1 First point of the first tangent.
     108                 :            :      * \param pt2_tg1 Second point of the first tangent.
     109                 :            :      * \param pt1_tg2 First point of the second tangent.
     110                 :            :      * \param pt2_tg2 Second point of the second tangent.
     111                 :            :      * \param pt1_tg3 First point of the third tangent.
     112                 :            :      * \param pt2_tg3 Second point of the third tangent.
     113                 :            :      * \param epsilon Value used to compare point.
     114                 :            :      * \param pos Point to determine which circle use in case of multi return.
     115                 :            :      * If the solution is not unique and pos is an empty point, an empty circle is returned. -- This case happens only when two tangets are parallels. (since QGIS 3.18)
     116                 :            :      *
     117                 :            :      * \see from3TangentsMulti()
     118                 :            :      *
     119                 :            :      * ### Example
     120                 :            :      *
     121                 :            :      * \code{.py}
     122                 :            :      *  # [(0 0), (5 0)] and [(5 5), (10 5)] are parallels
     123                 :            :      *  QgsCircle.from3Tangents(QgsPoint(0, 0), QgsPoint(5, 0), QgsPoint(5, 5), QgsPoint(10, 5), QgsPoint(2.5, 0), QgsPoint(7.5, 5))
     124                 :            :      *  # <QgsCircle: Empty>
     125                 :            :      *  QgsCircle.from3Tangents(QgsPoint(0, 0), QgsPoint(5, 0), QgsPoint(5, 5), QgsPoint(10, 5), QgsPoint(2.5, 0), QgsPoint(7.5, 5), pos=QgsPoint(2, 0))
     126                 :            :      *  # <QgsCircle: Circle (Center: Point (1.46446609406726203 2.49999999999999911), Radius: 2.5, Azimuth: 0)>
     127                 :            :      *  QgsCircle.from3Tangents(QgsPoint(0, 0), QgsPoint(5, 0), QgsPoint(5, 5), QgsPoint(10, 5), QgsPoint(2.5, 0), QgsPoint(7.5, 5), pos=QgsPoint(3, 0))
     128                 :            :      *  # <QgsCircle: Circle (Center: Point (8.53553390593273775 2.5), Radius: 2.5, Azimuth: 0)>
     129                 :            :      * \endcode
     130                 :            :      */
     131                 :            :     static QgsCircle from3Tangents( const QgsPoint &pt1_tg1, const QgsPoint &pt2_tg1,
     132                 :            :                                     const QgsPoint &pt1_tg2, const QgsPoint &pt2_tg2,
     133                 :            :                                     const QgsPoint &pt1_tg3, const QgsPoint &pt2_tg3,
     134                 :            :                                     double epsilon = 1E-8,
     135                 :            :                                     QgsPoint pos = QgsPoint() ) SIP_HOLDGIL;
     136                 :            : 
     137                 :            :     /**
     138                 :            :      * Returns an array of circle constructed by 3 tangents on the circle (aka inscribed circle of a triangle).
     139                 :            :      *
     140                 :            :      * The vector can contain 0, 1 or 2 circles:
     141                 :            :      *
     142                 :            :      * - 0: Impossible to construct a circle from 3 tangents (three parallel tangents)
     143                 :            :      * - 1: The three tangents make a triangle or when two tangents are parallel there are two possible circles (see examples).
     144                 :            :      *   If pos is not an empty point, we use its coordinates to determine which circle will be returned.
     145                 :            :      *   More precisely the circle that will be returned will be the one whose center is on the same side as pos relative to the third tangent.
     146                 :            :      * - 2: Returns both solutions when two tangents are parallel (this implies that pos is an empty point).
     147                 :            :      *
     148                 :            :      * Z and m values are dropped for the center point.
     149                 :            :      * The azimuth always takes the default value.
     150                 :            :      * \param pt1_tg1 First point of the first tangent.
     151                 :            :      * \param pt2_tg1 Second point of the first tangent.
     152                 :            :      * \param pt1_tg2 First point of the second tangent.
     153                 :            :      * \param pt2_tg2 Second point of the second tangent.
     154                 :            :      * \param pt1_tg3 First point of the third tangent.
     155                 :            :      * \param pt2_tg3 Second point of the third tangent.
     156                 :            :      * \param epsilon Value used to compare point.
     157                 :            :      * \param pos (optional) Point to determine which circle use in case of multi return.
     158                 :            :      *
     159                 :            :      * \see from3Tangents()
     160                 :            :      *
     161                 :            :      * ### Example
     162                 :            :      *
     163                 :            :      * \code{.py}
     164                 :            :      *
     165                 :            :      *  # [(0 0), (5 0)] and [(5 5), (10 5)] are parallels
     166                 :            :      *  QgsCircle.from3TangentsMulti(QgsPoint(0, 0), QgsPoint(5, 0), QgsPoint(5, 5), QgsPoint(10, 5), QgsPoint(2.5, 0), QgsPoint(7.5, 5))
     167                 :            :      *  # [<QgsCircle: Circle (Center: Point (8.53553390593273775 2.5), Radius: 2.5, Azimuth: 0)>, <QgsCircle: Circle (Center: Point (1.46446609406726203 2.49999999999999911), Radius: 2.5, Azimuth: 0)>]
     168                 :            :      *  QgsCircle.from3TangentsMulti(QgsPoint(0, 0), QgsPoint(5, 0), QgsPoint(5, 5), QgsPoint(10, 5), QgsPoint(2.5, 0), QgsPoint(7.5, 5), pos=QgsPoint(2, 0))
     169                 :            :      *  # [<QgsCircle: Circle (Center: Point (1.46446609406726203 2.49999999999999911), Radius: 2.5, Azimuth: 0)>]
     170                 :            :      *  QgsCircle.from3TangentsMulti(QgsPoint(0, 0), QgsPoint(5, 0), QgsPoint(5, 5), QgsPoint(10, 5), QgsPoint(2.5, 0), QgsPoint(7.5, 5), pos=QgsPoint(3, 0))
     171                 :            :      *  # [<QgsCircle: Circle (Center: Point (8.53553390593273775 2.5), Radius: 2.5, Azimuth: 0)>]
     172                 :            :      *  # [(0 0), (5 0)], [(5 5), (10 5)] and [(15 5), (20 5)] are parallels
     173                 :            :      *  QgsCircle.from3TangentsMulti(QgsPoint(0, 0), QgsPoint(5, 0), QgsPoint(5, 5), QgsPoint(10, 5), QgsPoint(15, 5), QgsPoint(20, 5))
     174                 :            :      *  # []
     175                 :            :      * \endcode
     176                 :            :      */
     177                 :            :     static QVector<QgsCircle> from3TangentsMulti( const QgsPoint &pt1_tg1, const QgsPoint &pt2_tg1,
     178                 :            :         const QgsPoint &pt1_tg2, const QgsPoint &pt2_tg2,
     179                 :            :         const QgsPoint &pt1_tg3, const QgsPoint &pt2_tg3,
     180                 :            :         double epsilon = 1E-8,
     181                 :            :         QgsPoint pos = QgsPoint() ) SIP_HOLDGIL;
     182                 :            : 
     183                 :            :     /**
     184                 :            :      * Constructs a circle by an extent (aka bounding box / QgsRectangle).
     185                 :            :      * The center point can have m value which is the result from the midpoint
     186                 :            :      * operation between \a pt1 and \a pt2. Z dimension is also supported and
     187                 :            :      * is retrieved from the first 3D point amongst \a pt1 and \a pt2.
     188                 :            :      * Axes are calculated from the 2D distance between \a pt1 and \a pt2.
     189                 :            :      * The azimuth always takes the default value.
     190                 :            :      * \param pt1 First corner.
     191                 :            :      * \param pt2 Second corner.
     192                 :            :      */
     193                 :            :     static QgsCircle fromExtent( const QgsPoint &pt1, const QgsPoint &pt2 ) SIP_HOLDGIL;
     194                 :            : 
     195                 :            :     /**
     196                 :            :      * Constructs the smallest circle from 3 points.
     197                 :            :      * Z and m values are dropped for the center point.
     198                 :            :      * The azimuth always takes the default value.
     199                 :            :      * If the points are colinear an empty circle is returned.
     200                 :            :      * \param pt1 First point.
     201                 :            :      * \param pt2 Second point.
     202                 :            :      * \param pt3 Third point.
     203                 :            :      * \param epsilon Value used to compare point.
     204                 :            :      */
     205                 :            :     static QgsCircle minimalCircleFrom3Points( const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double epsilon = 1E-8 ) SIP_HOLDGIL;
     206                 :            : 
     207                 :            :     /**
     208                 :            :      * Calculates the intersections points between this circle and an \a other circle.
     209                 :            :      *
     210                 :            :      * If found, the intersection points will be stored in \a intersection1 and \a intersection2.
     211                 :            :      *
     212                 :            :      * By default this method does not consider any z values and instead treats the circles as 2-dimensional.
     213                 :            :      * If \a useZ is set to TRUE, then an intersection will only occur if the z values of both circles are
     214                 :            :      * equal. In this case the points returned for \a intersection1 and \a intersection2 will contain
     215                 :            :      * the z value of the circle intersections.
     216                 :            :      *
     217                 :            :      * \returns number of intersection points found.
     218                 :            :      *
     219                 :            :      * \since QGIS 3.2
     220                 :            :      */
     221                 :            :     int intersections( const QgsCircle &other, QgsPoint &intersection1 SIP_OUT, QgsPoint &intersection2 SIP_OUT, bool useZ = false ) const;
     222                 :            : 
     223                 :            :     /**
     224                 :            :      * Calculates the tangent points between this circle and the point \a p.
     225                 :            :      *
     226                 :            :      * If found, the tangent points will be stored in \a pt1 and \a pt2.
     227                 :            :      *
     228                 :            :      * Note that this method is 2D only and does not consider the z-value of the circle.
     229                 :            :      *
     230                 :            :      * \returns TRUE if tangent was found.
     231                 :            :      *
     232                 :            :      *
     233                 :            :      * \see outerTangents() and innerTangents()
     234                 :            :      * \since QGIS 3.2
     235                 :            :      */
     236                 :            :     bool tangentToPoint( const QgsPointXY &p, QgsPointXY &pt1 SIP_OUT, QgsPointXY &pt2 SIP_OUT ) const;
     237                 :            : 
     238                 :            :     /**
     239                 :            :      * Calculates the outer tangent points between this circle
     240                 :            :      * and an \a other circle.
     241                 :            :      *
     242                 :            :      * The outer tangent points correspond to the points at which the two lines
     243                 :            :      * which are drawn so that they are tangential to both circles touch
     244                 :            :      * the circles.
     245                 :            :      *
     246                 :            :      * The first tangent line is described by the points
     247                 :            :      * stored in \a line1P1 and \a line1P2,
     248                 :            :      * and the second line is described by the points stored in \a line2P1
     249                 :            :      * and \a line2P2.
     250                 :            :      *
     251                 :            :      * Returns the number of tangents (either 0 or 2).
     252                 :            :      *
     253                 :            :      * Note that this method is 2D only and does not consider the z-value of the circle.
     254                 :            :      *
     255                 :            :      *
     256                 :            :      * \see tangentToPoint() and innerTangents()
     257                 :            :      * \since QGIS 3.2
     258                 :            :      */
     259                 :            :     int outerTangents( const QgsCircle &other,
     260                 :            :                        QgsPointXY &line1P1 SIP_OUT, QgsPointXY &line1P2 SIP_OUT,
     261                 :            :                        QgsPointXY &line2P1 SIP_OUT, QgsPointXY &line2P2 SIP_OUT ) const;
     262                 :            : 
     263                 :            :     /**
     264                 :            :      * Calculates the inner tangent points between this circle
     265                 :            :      * and an \a other circle.
     266                 :            :      *
     267                 :            :      * The inner tangent points correspond to the points at which the two lines
     268                 :            :      * which are drawn so that they are tangential to both circles but on
     269                 :            :      * different sides, touching the circles and crossing each other.
     270                 :            :      *
     271                 :            :      * The first tangent line is described by the points
     272                 :            :      * stored in \a line1P1 and \a line1P2,
     273                 :            :      * and the second line is described by the points stored in \a line2P1
     274                 :            :      * and \a line2P2.
     275                 :            :      *
     276                 :            :      * Returns the number of tangents (either 0 or 2).
     277                 :            :      *
     278                 :            :      * Note that this method is 2D only and does not consider the z-value of the circle.
     279                 :            :      *
     280                 :            :      *
     281                 :            :      * \see tangentToPoint() and outerTangents()
     282                 :            :      * \since QGIS 3.6
     283                 :            :      */
     284                 :            :     int innerTangents( const QgsCircle &other,
     285                 :            :                        QgsPointXY &line1P1 SIP_OUT, QgsPointXY &line1P2 SIP_OUT,
     286                 :            :                        QgsPointXY &line2P1 SIP_OUT, QgsPointXY &line2P2 SIP_OUT ) const;
     287                 :            : 
     288                 :            :     double area() const override SIP_HOLDGIL;
     289                 :            :     double perimeter() const override SIP_HOLDGIL;
     290                 :            : 
     291                 :            :     //inherited
     292                 :            :     // void setAzimuth(const double azimuth);
     293                 :            :     // double azimuth() const {return mAzimuth; }
     294                 :            : 
     295                 :            : 
     296                 :            :     /**
     297                 :            :      * Inherited method. Use setRadius instead.
     298                 :            :      * \see radius()
     299                 :            :      * \see setRadius()
     300                 :            :      */
     301                 :            :     void setSemiMajorAxis( double semiMajorAxis ) override SIP_HOLDGIL;
     302                 :            : 
     303                 :            :     /**
     304                 :            :      * Inherited method. Use setRadius instead.
     305                 :            :      * \see radius()
     306                 :            :      * \see setRadius()
     307                 :            :      */
     308                 :            :     void setSemiMinorAxis( double semiMinorAxis ) override SIP_HOLDGIL;
     309                 :            : 
     310                 :            :     //! Returns the radius of the circle
     311                 :         57 :     double radius() const SIP_HOLDGIL {return mSemiMajorAxis;}
     312                 :            :     //! Sets the radius of the circle
     313                 :          1 :     void setRadius( double radius ) SIP_HOLDGIL
     314                 :            :     {
     315                 :          1 :       mSemiMajorAxis = std::fabs( radius );
     316                 :          1 :       mSemiMinorAxis = mSemiMajorAxis;
     317                 :          1 :     }
     318                 :            : 
     319                 :            :     /**
     320                 :            :      * The four quadrants of the ellipse.
     321                 :            :      * They are oriented and started from North.
     322                 :            :      * \return quadrants defined by four points.
     323                 :            :      * \see quadrant()
     324                 :            :      */
     325                 :            :     QVector<QgsPoint> northQuadrant() const SIP_FACTORY;
     326                 :            : 
     327                 :            :     /**
     328                 :            :      * Returns a circular string from the circle.
     329                 :            :      * \param oriented If oriented is TRUE the start point is from azimuth instead from north.
     330                 :            :      */
     331                 :            :     QgsCircularString *toCircularString( bool oriented = false ) const;
     332                 :            : 
     333                 :            :     //! Returns TRUE if the circle contains the \a point.
     334                 :            :     bool contains( const QgsPoint &point, double epsilon = 1E-8 ) const;
     335                 :            : 
     336                 :            :     QgsRectangle boundingBox() const override;
     337                 :            : 
     338                 :            :     QString toString( int pointPrecision = 17, int radiusPrecision = 17, int azimuthPrecision = 2 ) const override;
     339                 :            : 
     340                 :            :     /**
     341                 :            :      * Returns a GML2 representation of the geometry.
     342                 :            :      * Since GML2 does not supports curve, it will be converted to a LineString.
     343                 :            :      * \param doc DOM document
     344                 :            :      * \param precision number of decimal places for coordinates
     345                 :            :      * \param ns XML namespace
     346                 :            :      * \param axisOrder Axis order for generated GML
     347                 :            :      * \see asGml3()
     348                 :            :      */
     349                 :            :     QDomElement asGml2( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const;
     350                 :            : 
     351                 :            :     /**
     352                 :            :      * Returns a GML3 representation of the geometry.
     353                 :            :      *
     354                 :            :      * From the GML3 description:
     355                 :            :      * A Circle is an arc whose ends coincide to form a simple closed loop.
     356                 :            :      * The three control points shall be distinct non-co-linear points for
     357                 :            :      * the circle to be unambiguously defined. The arc is simply extended
     358                 :            :      * past the third control point until the first control point is encountered.
     359                 :            :      *
     360                 :            :      * Coordinates are taken from quadrant North, East and South.
     361                 :            :      *
     362                 :            :      * \param doc DOM document
     363                 :            :      * \param precision number of decimal places for coordinates
     364                 :            :      * \param ns XML namespace
     365                 :            :      * \param axisOrder Axis order for generated GML
     366                 :            :      * \see asGml2()
     367                 :            :      */
     368                 :            :     QDomElement asGml3( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const;
     369                 :            : 
     370                 :            : #ifdef SIP_RUN
     371                 :            :     SIP_PYOBJECT __repr__();
     372                 :            :     % MethodCode
     373                 :            :     QString str = QStringLiteral( "<QgsCircle: %1>" ).arg( sipCpp->toString() );
     374                 :            :     sipRes = PyUnicode_FromString( str.toUtf8().constData() );
     375                 :            :     % End
     376                 :            : #endif
     377                 :            : };
     378                 :            : 
     379                 :            : #endif // QGSCIRCLE_H

Generated by: LCOV version 1.14