QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgscircle.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgscircle.cpp
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 #include "qgscircle.h"
19 #include "qgslinestring.h"
20 #include "qgsgeometryutils.h"
21 #include "qgstriangle.h"
22 
23 #include <memory>
24 #include <utility>
25 
27  QgsEllipse( QgsPoint(), 0.0, 0.0, 0.0 )
28 {
29 
30 }
31 
32 QgsCircle::QgsCircle( const QgsPoint &center, double radius, double azimuth ) :
33  QgsEllipse( center, radius, radius, azimuth )
34 {
35 
36 }
37 
39 {
41  const double azimuth = QgsGeometryUtils::lineAngle( pt1.x(), pt1.y(), pt2.x(), pt2.y() ) * 180.0 / M_PI;
42  const double radius = pt1.distance( pt2 ) / 2.0;
43 
45 
46  return QgsCircle( center, radius, azimuth );
47 }
48 
49 static bool isPerpendicular( const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double epsilon )
50 {
51  // check the given point are perpendicular to x or y axis
52 
53  const double yDelta_a = pt2.y() - pt1.y();
54  const double xDelta_a = pt2.x() - pt1.x();
55  const double yDelta_b = pt3.y() - pt2.y();
56  const double xDelta_b = pt3.x() - pt2.x();
57 
58  if ( ( std::fabs( xDelta_a ) <= epsilon ) && ( std::fabs( yDelta_b ) <= epsilon ) )
59  {
60  return false;
61  }
62 
63  if ( std::fabs( yDelta_a ) <= epsilon )
64  {
65  return true;
66  }
67  else if ( std::fabs( yDelta_b ) <= epsilon )
68  {
69  return true;
70  }
71  else if ( std::fabs( xDelta_a ) <= epsilon )
72  {
73  return true;
74  }
75  else if ( std::fabs( xDelta_b ) <= epsilon )
76  {
77  return true;
78  }
79 
80  return false;
81 
82 }
83 
84 QgsCircle QgsCircle::from3Points( const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double epsilon )
85 {
86  QgsPoint p1, p2, p3;
87 
88  if ( !isPerpendicular( pt1, pt2, pt3, epsilon ) )
89  {
90  p1 = pt1;
91  p2 = pt2;
92  p3 = pt3;
93  }
94  else if ( !isPerpendicular( pt1, pt3, pt2, epsilon ) )
95  {
96  p1 = pt1;
97  p2 = pt3;
98  p3 = pt2;
99  }
100  else if ( !isPerpendicular( pt2, pt1, pt3, epsilon ) )
101  {
102  p1 = pt2;
103  p2 = pt1;
104  p3 = pt3;
105  }
106  else if ( !isPerpendicular( pt2, pt3, pt1, epsilon ) )
107  {
108  p1 = pt2;
109  p2 = pt3;
110  p3 = pt1;
111  }
112  else if ( !isPerpendicular( pt3, pt2, pt1, epsilon ) )
113  {
114  p1 = pt3;
115  p2 = pt2;
116  p3 = pt1;
117  }
118  else if ( !isPerpendicular( pt3, pt1, pt2, epsilon ) )
119  {
120  p1 = pt3;
121  p2 = pt1;
122  p3 = pt2;
123  }
124  else
125  {
126  return QgsCircle();
127  }
129  double radius = -0.0;
130  // Paul Bourke's algorithm
131  const double yDelta_a = p2.y() - p1.y();
132  const double xDelta_a = p2.x() - p1.x();
133  const double yDelta_b = p3.y() - p2.y();
134  const double xDelta_b = p3.x() - p2.x();
135 
136  if ( qgsDoubleNear( xDelta_a, 0.0, epsilon ) || qgsDoubleNear( xDelta_b, 0.0, epsilon ) )
137  {
138  return QgsCircle();
139  }
140 
141  const double aSlope = yDelta_a / xDelta_a;
142  const double bSlope = yDelta_b / xDelta_b;
143 
144  // set z and m coordinate for center
146 
147  if ( ( std::fabs( xDelta_a ) <= epsilon ) && ( std::fabs( yDelta_b ) <= epsilon ) )
148  {
149  center.setX( 0.5 * ( p2.x() + p3.x() ) );
150  center.setY( 0.5 * ( p1.y() + p2.y() ) );
151  radius = center.distance( pt1 );
152 
153  return QgsCircle( center, radius );
154  }
155 
156  if ( std::fabs( aSlope - bSlope ) <= epsilon )
157  {
158  return QgsCircle();
159  }
160 
161  center.setX(
162  ( aSlope * bSlope * ( p1.y() - p3.y() ) +
163  bSlope * ( p1.x() + p2.x() ) -
164  aSlope * ( p2.x() + p3.x() ) ) /
165  ( 2.0 * ( bSlope - aSlope ) )
166  );
167  center.setY(
168  -1.0 * ( center.x() - ( p1.x() + p2.x() ) / 2.0 ) /
169  aSlope + ( p1.y() + p2.y() ) / 2.0
170  );
171 
172  radius = center.distance( p1 );
173 
174  return QgsCircle( center, radius );
175 }
176 
177 QgsCircle QgsCircle::fromCenterDiameter( const QgsPoint &center, double diameter, double azimuth )
178 {
179  return QgsCircle( center, diameter / 2.0, azimuth );
180 }
181 
183 {
184  const double azimuth = QgsGeometryUtils::lineAngle( center.x(), center.y(), pt1.x(), pt1.y() ) * 180.0 / M_PI;
185 
186  QgsPoint centerPt( center );
188 
189  return QgsCircle( centerPt, centerPt.distance( pt1 ), azimuth );
190 }
191 
192 static QVector<QgsCircle> from2ParallelsLine( const QgsPoint &pt1_par1, const QgsPoint &pt2_par1, const QgsPoint &pt1_par2, const QgsPoint &pt2_par2, const QgsPoint &pt1_line1, const QgsPoint &pt2_line1, const QgsPoint &pos, double epsilon )
193 {
194  const double radius = QgsGeometryUtils::perpendicularSegment( pt1_par2, pt1_par1, pt2_par1 ).length() / 2.0;
195 
196  bool isInter;
197  const QgsPoint ptInter;
198  QVector<QgsCircle> circles;
199 
200  QgsPoint ptInter_par1line1, ptInter_par2line1;
201  double angle1, angle2;
202  double x, y;
203  QgsGeometryUtils::angleBisector( pt1_par1.x(), pt1_par1.y(), pt2_par1.x(), pt2_par1.y(), pt1_line1.x(), pt1_line1.y(), pt2_line1.x(), pt2_line1.y(), x, y, angle1 );
204  ptInter_par1line1.setX( x );
205  ptInter_par1line1.setY( y );
206 
207  QgsGeometryUtils::angleBisector( pt1_par2.x(), pt1_par2.y(), pt2_par2.x(), pt2_par2.y(), pt1_line1.x(), pt1_line1.y(), pt2_line1.x(), pt2_line1.y(), x, y, angle2 );
208  ptInter_par2line1.setX( x );
209  ptInter_par2line1.setY( y );
210 
211  QgsPoint center;
212  QgsGeometryUtils::segmentIntersection( ptInter_par1line1, ptInter_par1line1.project( 1.0, angle1 ), ptInter_par2line1, ptInter_par2line1.project( 1.0, angle2 ), center, isInter, epsilon, true );
213  if ( isInter )
214  {
215  if ( !pos.isEmpty() )
216  {
217  if ( QgsGeometryUtils::leftOfLine( center, pt1_line1, pt2_line1 ) == QgsGeometryUtils::leftOfLine( pos, pt1_line1, pt2_line1 ) )
218  {
219  circles.append( QgsCircle( center, radius ) );
220  }
221  }
222  else
223  {
224  circles.append( QgsCircle( center, radius ) );
225  }
226  }
227 
228  QgsGeometryUtils::segmentIntersection( ptInter_par1line1, ptInter_par1line1.project( 1.0, angle1 ), ptInter_par2line1, ptInter_par2line1.project( 1.0, angle2 + 90.0 ), center, isInter, epsilon, true );
229  if ( isInter )
230  {
231  if ( !pos.isEmpty() )
232  {
233  if ( QgsGeometryUtils::leftOfLine( center, pt1_line1, pt2_line1 ) == QgsGeometryUtils::leftOfLine( pos, pt1_line1, pt2_line1 ) )
234  {
235  circles.append( QgsCircle( center, radius ) );
236  }
237  }
238  else
239  {
240  circles.append( QgsCircle( center, radius ) );
241  }
242  }
243 
244  QgsGeometryUtils::segmentIntersection( ptInter_par1line1, ptInter_par1line1.project( 1.0, angle1 + 90.0 ), ptInter_par2line1, ptInter_par2line1.project( 1.0, angle2 ), center, isInter, epsilon, true );
245  if ( isInter && !circles.contains( QgsCircle( center, radius ) ) )
246  {
247  if ( !pos.isEmpty() )
248  {
249  if ( QgsGeometryUtils::leftOfLine( center, pt1_line1, pt2_line1 ) == QgsGeometryUtils::leftOfLine( pos, pt1_line1, pt2_line1 ) )
250  {
251  circles.append( QgsCircle( center, radius ) );
252  }
253  }
254  else
255  {
256  circles.append( QgsCircle( center, radius ) );
257  }
258  }
259  QgsGeometryUtils::segmentIntersection( ptInter_par1line1, ptInter_par1line1.project( 1.0, angle1 + 90.0 ), ptInter_par2line1, ptInter_par2line1.project( 1.0, angle2 + 90.0 ), center, isInter, epsilon, true );
260  if ( isInter && !circles.contains( QgsCircle( center, radius ) ) )
261  {
262  if ( !pos.isEmpty() )
263  {
264  if ( QgsGeometryUtils::leftOfLine( center, pt1_line1, pt2_line1 ) == QgsGeometryUtils::leftOfLine( pos, pt1_line1, pt2_line1 ) )
265  {
266  circles.append( QgsCircle( center, radius ) );
267  }
268  }
269  else
270  {
271  circles.append( QgsCircle( center, radius ) );
272  }
273  }
274 
275  return circles;
276 }
277 
278 QVector<QgsCircle> QgsCircle::from3TangentsMulti( const QgsPoint &pt1_tg1, const QgsPoint &pt2_tg1, const QgsPoint &pt1_tg2, const QgsPoint &pt2_tg2, const QgsPoint &pt1_tg3, const QgsPoint &pt2_tg3, double epsilon, const QgsPoint &pos )
279 {
280  QgsPoint p1, p2, p3;
281  bool isIntersect_tg1tg2 = false;
282  bool isIntersect_tg1tg3 = false;
283  bool isIntersect_tg2tg3 = false;
284  QgsGeometryUtils::segmentIntersection( pt1_tg1, pt2_tg1, pt1_tg2, pt2_tg2, p1, isIntersect_tg1tg2, epsilon );
285  QgsGeometryUtils::segmentIntersection( pt1_tg1, pt2_tg1, pt1_tg3, pt2_tg3, p2, isIntersect_tg1tg3, epsilon );
286  QgsGeometryUtils::segmentIntersection( pt1_tg2, pt2_tg2, pt1_tg3, pt2_tg3, p3, isIntersect_tg2tg3, epsilon );
287 
288  QVector<QgsCircle> circles;
289  if ( !isIntersect_tg1tg2 && !isIntersect_tg2tg3 ) // three lines are parallels
290  return circles;
291 
292  if ( !isIntersect_tg1tg2 )
293  return from2ParallelsLine( pt1_tg1, pt2_tg1, pt1_tg2, pt2_tg2, pt1_tg3, pt2_tg3, pos, epsilon );
294  else if ( !isIntersect_tg1tg3 )
295  return from2ParallelsLine( pt1_tg1, pt2_tg1, pt1_tg3, pt2_tg3, pt1_tg2, pt2_tg2, pos, epsilon );
296  else if ( !isIntersect_tg2tg3 )
297  return from2ParallelsLine( pt1_tg2, pt2_tg2, pt1_tg3, pt2_tg3, pt1_tg1, pt1_tg1, pos, epsilon );
298 
299  if ( p1.is3D() )
300  {
301  p1.convertTo( QgsWkbTypes::dropZ( p1.wkbType() ) );
302  }
303 
304  if ( p2.is3D() )
305  {
306  p2.convertTo( QgsWkbTypes::dropZ( p2.wkbType() ) );
307  }
308 
309  if ( p3.is3D() )
310  {
311  p3.convertTo( QgsWkbTypes::dropZ( p3.wkbType() ) );
312  }
313 
314  circles.append( QgsTriangle( p1, p2, p3 ).inscribedCircle() );
315  return circles;
316 }
317 
318 QgsCircle QgsCircle::from3Tangents( const QgsPoint &pt1_tg1, const QgsPoint &pt2_tg1, const QgsPoint &pt1_tg2, const QgsPoint &pt2_tg2, const QgsPoint &pt1_tg3, const QgsPoint &pt2_tg3, double epsilon, const QgsPoint &pos )
319 {
320  const QVector<QgsCircle> circles = from3TangentsMulti( pt1_tg1, pt2_tg1, pt1_tg2, pt2_tg2, pt1_tg3, pt2_tg3, epsilon, pos );
321  if ( circles.length() != 1 )
322  return QgsCircle();
323  return circles.at( 0 );
324 }
325 
326 QgsCircle QgsCircle::minimalCircleFrom3Points( const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double epsilon )
327 {
328  const double l1 = pt2.distance( pt3 );
329  const double l2 = pt3.distance( pt1 );
330  const double l3 = pt1.distance( pt2 );
331 
332  if ( ( l1 * l1 ) - ( l2 * l2 + l3 * l3 ) >= epsilon )
333  return QgsCircle().from2Points( pt2, pt3 );
334  else if ( ( l2 * l2 ) - ( l1 * l1 + l3 * l3 ) >= epsilon )
335  return QgsCircle().from2Points( pt3, pt1 );
336  else if ( ( l3 * l3 ) - ( l1 * l1 + l2 * l2 ) >= epsilon )
337  return QgsCircle().from2Points( pt1, pt2 );
338  else
339  return QgsCircle().from3Points( pt1, pt2, pt3, epsilon );
340 }
341 
342 int QgsCircle::intersections( const QgsCircle &other, QgsPoint &intersection1, QgsPoint &intersection2, bool useZ ) const
343 {
344  if ( useZ && mCenter.is3D() && other.center().is3D() && !qgsDoubleNear( mCenter.z(), other.center().z() ) )
345  return 0;
346 
347  QgsPointXY int1, int2;
348 
350  QgsPointXY( other.center() ), other.radius(),
351  int1, int2 );
352  if ( res == 0 )
353  return 0;
354 
355  intersection1 = QgsPoint( int1 );
356  intersection2 = QgsPoint( int2 );
357  if ( useZ && mCenter.is3D() )
358  {
359  intersection1.addZValue( mCenter.z() );
360  intersection2.addZValue( mCenter.z() );
361  }
362  return res;
363 }
364 
365 bool QgsCircle::tangentToPoint( const QgsPointXY &p, QgsPointXY &pt1, QgsPointXY &pt2 ) const
366 {
368 }
369 
370 int QgsCircle::outerTangents( const QgsCircle &other, QgsPointXY &line1P1, QgsPointXY &line1P2, QgsPointXY &line2P1, QgsPointXY &line2P2 ) const
371 {
373  QgsPointXY( other.center() ), other.radius(), line1P1, line1P2, line2P1, line2P2 );
374 }
375 
376 int QgsCircle::innerTangents( const QgsCircle &other, QgsPointXY &line1P1, QgsPointXY &line1P2, QgsPointXY &line2P1, QgsPointXY &line2P2 ) const
377 {
379  QgsPointXY( other.center() ), other.radius(), line1P1, line1P2, line2P1, line2P2 );
380 }
381 
383 {
384  const double delta_x = std::fabs( pt1.x() - pt2.x() );
385  const double delta_y = std::fabs( pt1.x() - pt2.y() );
386  if ( !qgsDoubleNear( delta_x, delta_y ) )
387  {
388  return QgsCircle();
389  }
390 
393 
394  return QgsCircle( center, delta_x / 2.0, 0 );
395 }
396 
397 double QgsCircle::area() const
398 {
399  return M_PI * mSemiMajorAxis * mSemiMajorAxis;
400 }
401 
402 double QgsCircle::perimeter() const
403 {
404  return 2.0 * M_PI * mSemiMajorAxis;
405 }
406 
407 void QgsCircle::setSemiMajorAxis( const double semiMajorAxis )
408 {
409  mSemiMajorAxis = std::fabs( semiMajorAxis );
411 }
412 
413 void QgsCircle::setSemiMinorAxis( const double semiMinorAxis )
414 {
415  mSemiMajorAxis = std::fabs( semiMinorAxis );
417 }
418 
419 QVector<QgsPoint> QgsCircle::northQuadrant() const
420 {
421  QVector<QgsPoint> quad;
422  quad.append( QgsPoint( mCenter.x(), mCenter.y() + mSemiMajorAxis, mCenter.z(), mCenter.m() ) );
423  quad.append( QgsPoint( mCenter.x() + mSemiMajorAxis, mCenter.y(), mCenter.z(), mCenter.m() ) );
424  quad.append( QgsPoint( mCenter.x(), mCenter.y() - mSemiMajorAxis, mCenter.z(), mCenter.m() ) );
425  quad.append( QgsPoint( mCenter.x() - mSemiMajorAxis, mCenter.y(), mCenter.z(), mCenter.m() ) );
426 
427  return quad;
428 }
429 
431 {
432  std::unique_ptr<QgsCircularString> circString( new QgsCircularString() );
434  QVector<QgsPoint> quad;
435  if ( oriented )
436  {
437  quad = quadrant();
438  }
439  else
440  {
441  quad = northQuadrant();
442  }
443  quad.append( quad.at( 0 ) );
444  for ( QVector<QgsPoint>::const_iterator it = quad.constBegin(); it != quad.constEnd(); ++it )
445  {
446  points.append( *it );
447  }
448  circString->setPoints( points );
449 
450  return circString.release();
451 }
452 
453 bool QgsCircle::contains( const QgsPoint &point, double epsilon ) const
454 {
455  return ( mCenter.distance( point ) <= mSemiMajorAxis + epsilon );
456 }
457 
459 {
461 }
462 
463 QString QgsCircle::toString( int pointPrecision, int radiusPrecision, int azimuthPrecision ) const
464 {
465  QString rep;
466  if ( isEmpty() )
467  rep = QStringLiteral( "Empty" );
468  else
469  rep = QStringLiteral( "Circle (Center: %1, Radius: %2, Azimuth: %3)" )
470  .arg( mCenter.asWkt( pointPrecision ), 0, 's' )
471  .arg( qgsDoubleToString( mSemiMajorAxis, radiusPrecision ), 0, 'f' )
472  .arg( qgsDoubleToString( mAzimuth, azimuthPrecision ), 0, 'f' );
473 
474  return rep;
475 
476 }
477 
478 QDomElement QgsCircle::asGml2( QDomDocument &doc, int precision, const QString &ns, const QgsAbstractGeometry::AxisOrder axisOrder ) const
479 {
480  // Gml2 does not support curve. It will be converted to a linestring via CircularString
481  std::unique_ptr< QgsCircularString > circularString( toCircularString() );
482  const QDomElement gml = circularString->asGml2( doc, precision, ns, axisOrder );
483  return gml;
484 }
485 
486 QDomElement QgsCircle::asGml3( QDomDocument &doc, int precision, const QString &ns, const QgsAbstractGeometry::AxisOrder axisOrder ) const
487 {
488  QgsPointSequence pts;
489  pts << northQuadrant().at( 0 ) << northQuadrant().at( 1 ) << northQuadrant().at( 2 );
490 
491  QDomElement elemCircle = doc.createElementNS( ns, QStringLiteral( "Circle" ) );
492 
493  if ( isEmpty() )
494  return elemCircle;
495 
496  elemCircle.appendChild( QgsGeometryUtils::pointsToGML3( pts, doc, precision, ns, mCenter.is3D(), axisOrder ) );
497  return elemCircle;
498 }
QgsCircle::contains
bool contains(const QgsPoint &point, double epsilon=1E-8) const
Returns true if the circle contains the point.
Definition: qgscircle.cpp:453
QgsEllipse
Ellipse geometry type.
Definition: qgsellipse.h:39
QgsCircle::outerTangents
int outerTangents(const QgsCircle &other, QgsPointXY &line1P1, QgsPointXY &line1P2, QgsPointXY &line2P1, QgsPointXY &line2P2) const
Calculates the outer tangent points between this circle and an other circle.
Definition: qgscircle.cpp:370
QgsCircle::toString
QString toString(int pointPrecision=17, int radiusPrecision=17, int azimuthPrecision=2) const override
returns a string representation of the ellipse.
Definition: qgscircle.cpp:463
QgsEllipse::semiMajorAxis
double semiMajorAxis() const SIP_HOLDGIL
Returns the semi-major axis.
Definition: qgsellipse.h:127
QgsEllipse::mSemiMajorAxis
double mSemiMajorAxis
Definition: qgsellipse.h:253
QgsCircle::setSemiMajorAxis
void setSemiMajorAxis(double semiMajorAxis) override SIP_HOLDGIL
Inherited method.
Definition: qgscircle.cpp:407
QgsCircle
Circle geometry type.
Definition: qgscircle.h:43
QgsCircle::from3Tangents
static QgsCircle from3Tangents(const QgsPoint &pt1_tg1, const QgsPoint &pt2_tg1, const QgsPoint &pt1_tg2, const QgsPoint &pt2_tg2, const QgsPoint &pt1_tg3, const QgsPoint &pt2_tg3, double epsilon=1E-8, const QgsPoint &pos=QgsPoint()) SIP_HOLDGIL
Constructs a circle by 3 tangents on the circle (aka inscribed circle of a triangle).
Definition: qgscircle.cpp:318
QgsEllipse::mAzimuth
double mAzimuth
Definition: qgsellipse.h:255
QgsCircle::minimalCircleFrom3Points
static QgsCircle minimalCircleFrom3Points(const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double epsilon=1E-8) SIP_HOLDGIL
Constructs the smallest circle from 3 points.
Definition: qgscircle.cpp:326
QgsGeometryUtils::perpendicularSegment
static QgsLineString perpendicularSegment(const QgsPoint &p, const QgsPoint &s1, const QgsPoint &s2) SIP_HOLDGIL
Create a perpendicular line segment from p to segment [s1, s2].
Definition: qgsgeometryutils.cpp:1586
QgsLineString::length
double length() const override SIP_HOLDGIL
Returns the planar, 2-dimensional length of the geometry.
Definition: qgslinestring.cpp:833
qgslinestring.h
QgsPoint::distance
double distance(double x, double y) const SIP_HOLDGIL
Returns the Cartesian 2D distance between this point and a specified x, y coordinate.
Definition: qgspoint.h:360
QgsPoint
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:48
QgsCircle::innerTangents
int innerTangents(const QgsCircle &other, QgsPointXY &line1P1, QgsPointXY &line1P2, QgsPointXY &line2P1, QgsPointXY &line2P2) const
Calculates the inner tangent points between this circle and an other circle.
Definition: qgscircle.cpp:376
QgsPoint::asWkt
QString asWkt(int precision=17) const override
Returns a WKT representation of the geometry.
Definition: qgspoint.cpp:264
QgsPoint::addZValue
bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value.
Definition: qgspoint.cpp:551
QgsCircle::boundingBox
QgsRectangle boundingBox() const override
Returns the minimal bounding box for the ellipse.
Definition: qgscircle.cpp:458
QgsCircle::area
double area() const override SIP_HOLDGIL
The area of the ellipse.
Definition: qgscircle.cpp:397
QgsGeometryUtils::lineAngle
static double lineAngle(double x1, double y1, double x2, double y2) SIP_HOLDGIL
Calculates the direction of line joining two points in radians, clockwise from the north direction.
Definition: qgsgeometryutils.cpp:1641
QgsPoint::z
double z
Definition: qgspoint.h:71
QgsGeometryUtils::circleCircleOuterTangents
static int circleCircleOuterTangents(const QgsPointXY &center1, double radius1, const QgsPointXY &center2, double radius2, QgsPointXY &line1P1, QgsPointXY &line1P2, QgsPointXY &line2P1, QgsPointXY &line2P2) SIP_HOLDGIL
Calculates the outer tangent points for two circles, centered at center1 and center2 and with radii o...
Definition: qgsgeometryutils.cpp:479
QgsEllipse::quadrant
virtual QVector< QgsPoint > quadrant() const
The four quadrants of the ellipse.
Definition: qgsellipse.cpp:177
QgsGeometryUtils::leftOfLine
static int leftOfLine(const double x, const double y, const double x1, const double y1, const double x2, const double y2) SIP_HOLDGIL
Returns a value < 0 if the point (x, y) is left of the line from (x1, y1) -> (x2, y2).
Definition: qgsgeometryutils.cpp:605
QgsEllipse::isEmpty
virtual bool isEmpty() const SIP_HOLDGIL
An ellipse is empty if axes are equal to 0.
Definition: qgsellipse.cpp:118
QgsEllipse::points
virtual QgsPointSequence points(unsigned int segments=36) const
Returns a list of points with segmentation from segments.
Definition: qgsellipse.cpp:188
QgsGeometryUtils::circleCircleIntersections
static int circleCircleIntersections(const QgsPointXY &center1, double radius1, const QgsPointXY &center2, double radius2, QgsPointXY &intersection1, QgsPointXY &intersection2) SIP_HOLDGIL
Calculates the intersections points between the circle with center center1 and radius radius1 and the...
Definition: qgsgeometryutils.cpp:391
QgsCircle::from3Points
static QgsCircle from3Points(const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double epsilon=1E-8) SIP_HOLDGIL
Constructs a circle by 3 points on the circle.
Definition: qgscircle.cpp:84
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:41
QgsPoint::project
QgsPoint project(double distance, double azimuth, double inclination=90.0) const SIP_HOLDGIL
Returns a new point which corresponds to this point projected by a specified distance with specified ...
Definition: qgspoint.cpp:735
qgsDoubleToString
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Definition: qgis.h:2204
QgsCircle::from3TangentsMulti
static QVector< QgsCircle > from3TangentsMulti(const QgsPoint &pt1_tg1, const QgsPoint &pt2_tg1, const QgsPoint &pt1_tg2, const QgsPoint &pt2_tg2, const QgsPoint &pt1_tg3, const QgsPoint &pt2_tg3, double epsilon=1E-8, const QgsPoint &pos=QgsPoint()) SIP_HOLDGIL
Returns an array of circle constructed by 3 tangents on the circle (aka inscribed circle of a triangl...
Definition: qgscircle.cpp:278
QgsCircle::from2Points
static QgsCircle from2Points(const QgsPoint &pt1, const QgsPoint &pt2) SIP_HOLDGIL
Constructs a circle by 2 points on the circle.
Definition: qgscircle.cpp:38
QgsPoint::y
double y
Definition: qgspoint.h:70
precision
int precision
Definition: qgswfsgetfeature.cpp:103
QgsCircle::northQuadrant
QVector< QgsPoint > northQuadrant() const
The four quadrants of the ellipse.
Definition: qgscircle.cpp:419
QgsCircle::intersections
int intersections(const QgsCircle &other, QgsPoint &intersection1, QgsPoint &intersection2, bool useZ=false) const
Calculates the intersections points between this circle and an other circle.
Definition: qgscircle.cpp:342
QgsCircularString
Circular string geometry type.
Definition: qgscircularstring.h:34
QgsAbstractGeometry::wkbType
QgsWkbTypes::Type wkbType() const SIP_HOLDGIL
Returns the WKB type of the geometry.
Definition: qgsabstractgeometry.h:206
QgsEllipse::semiMinorAxis
double semiMinorAxis() const SIP_HOLDGIL
Returns the semi-minor axis.
Definition: qgsellipse.h:133
QgsAbstractGeometry::AxisOrder
AxisOrder
Axis order for GML generation.
Definition: qgsabstractgeometry.h:138
QgsEllipse::mSemiMinorAxis
double mSemiMinorAxis
Definition: qgsellipse.h:254
qgsDoubleNear
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:2265
qgscircle.h
QgsEllipse::azimuth
double azimuth() const SIP_HOLDGIL
Returns the azimuth.
Definition: qgsellipse.h:139
QgsCircle::radius
double radius() const SIP_HOLDGIL
Returns the radius of the circle.
Definition: qgscircle.h:311
qgstriangle.h
QgsCircle::fromCenterDiameter
static QgsCircle fromCenterDiameter(const QgsPoint &center, double diameter, double azimuth=0) SIP_HOLDGIL
Constructs a circle by a center point and a diameter.
Definition: qgscircle.cpp:177
QgsPoint::setX
void setX(double x) SIP_HOLDGIL
Sets the point's x-coordinate.
Definition: qgspoint.h:297
QgsCircle::toCircularString
QgsCircularString * toCircularString(bool oriented=false) const
Returns a circular string from the circle.
Definition: qgscircle.cpp:430
QgsPoint::m
double m
Definition: qgspoint.h:72
QgsEllipse::mCenter
QgsPoint mCenter
Definition: qgsellipse.h:252
QgsWkbTypes::dropZ
static Type dropZ(Type type) SIP_HOLDGIL
Drops the z dimension (if present) for a WKB type and returns the new type.
Definition: qgswkbtypes.h:1237
QgsGeometryUtils::segmentIntersection
static bool segmentIntersection(const QgsPoint &p1, const QgsPoint &p2, const QgsPoint &q1, const QgsPoint &q2, QgsPoint &intersectionPoint, bool &isIntersection, double tolerance=1e-8, bool acceptImproperIntersection=false) SIP_HOLDGIL
Compute the intersection between two segments.
Definition: qgsgeometryutils.cpp:277
QgsCircle::QgsCircle
QgsCircle()
Definition: qgscircle.cpp:26
QgsEllipse::center
QgsPoint center() const SIP_HOLDGIL
Returns the center point.
Definition: qgsellipse.h:121
QgsCircle::tangentToPoint
bool tangentToPoint(const QgsPointXY &p, QgsPointXY &pt1, QgsPointXY &pt2) const
Calculates the tangent points between this circle and the point p.
Definition: qgscircle.cpp:365
QgsCircle::setSemiMinorAxis
void setSemiMinorAxis(double semiMinorAxis) override SIP_HOLDGIL
Inherited method.
Definition: qgscircle.cpp:413
QgsCircle::perimeter
double perimeter() const override SIP_HOLDGIL
The circumference of the ellipse using first approximation of Ramanujan.
Definition: qgscircle.cpp:402
qgsgeometryutils.h
QgsAbstractGeometry::is3D
bool is3D() const SIP_HOLDGIL
Returns true if the geometry is 3D and contains a z-value.
Definition: qgsabstractgeometry.h:219
QgsPointXY
A class to represent a 2D point.
Definition: qgspointxy.h:58
QgsGeometryUtils::pointsToGML3
static QDomElement pointsToGML3(const QgsPointSequence &points, QDomDocument &doc, int precision, const QString &ns, bool is3D, QgsAbstractGeometry::AxisOrder axisOrder=QgsAbstractGeometry::AxisOrder::XY)
Returns a gml::posList DOM element.
Definition: qgsgeometryutils.cpp:1282
QgsGeometryUtils::midpoint
static QgsPoint midpoint(const QgsPoint &pt1, const QgsPoint &pt2) SIP_HOLDGIL
Returns a middle point between points pt1 and pt2.
Definition: qgsgeometryutils.cpp:1500
QgsGeometryUtils::angleBisector
static bool angleBisector(double aX, double aY, double bX, double bY, double cX, double cY, double dX, double dY, double &pointX, double &pointY, double &angle) SIP_HOLDGIL
Returns the point (pointX, pointY) forming the bisector from segment (aX aY) (bX bY) and segment (bX,...
Definition: qgsgeometryutils.cpp:1880
QgsGeometryUtils::transferFirstZOrMValueToPoint
static bool transferFirstZOrMValueToPoint(Iterator verticesBegin, Iterator verticesEnd, QgsPoint &point)
A Z or M dimension is added to point if one of the points in the list points contains Z or M value.
Definition: qgsgeometryutils.h:885
QgsPointSequence
QVector< QgsPoint > QgsPointSequence
Definition: qgsabstractgeometry.h:52
QgsGeometryUtils::circleCircleInnerTangents
static int circleCircleInnerTangents(const QgsPointXY &center1, double radius1, const QgsPointXY &center2, double radius2, QgsPointXY &line1P1, QgsPointXY &line1P2, QgsPointXY &line2P1, QgsPointXY &line2P2) SIP_HOLDGIL
Calculates the inner tangent points for two circles, centered at center1 and center2 and with radii o...
Definition: qgsgeometryutils.cpp:515
QgsCircle::fromCenterPoint
static QgsCircle fromCenterPoint(const QgsPoint &center, const QgsPoint &pt1) SIP_HOLDGIL
Constructs a circle by a center point and another point.
Definition: qgscircle.cpp:182
QgsCircle::asGml3
QDomElement asGml3(QDomDocument &doc, int precision=17, const QString &ns="gml", QgsAbstractGeometry::AxisOrder axisOrder=QgsAbstractGeometry::AxisOrder::XY) const
Returns a GML3 representation of the geometry.
Definition: qgscircle.cpp:486
QgsPoint::convertTo
bool convertTo(QgsWkbTypes::Type type) override
Converts the geometry to a specified type.
Definition: qgspoint.cpp:620
QgsPoint::isEmpty
bool isEmpty() const override SIP_HOLDGIL
Returns true if the geometry is empty.
Definition: qgspoint.cpp:767
QgsPoint::setY
void setY(double y) SIP_HOLDGIL
Sets the point's y-coordinate.
Definition: qgspoint.h:308
QgsCircle::fromExtent
static QgsCircle fromExtent(const QgsPoint &pt1, const QgsPoint &pt2) SIP_HOLDGIL
Constructs a circle by an extent (aka bounding box / QgsRectangle).
Definition: qgscircle.cpp:382
QgsGeometryUtils::tangentPointAndCircle
static bool tangentPointAndCircle(const QgsPointXY &center, double radius, const QgsPointXY &p, QgsPointXY &pt1, QgsPointXY &pt2) SIP_HOLDGIL
Calculates the tangent points between the circle with the specified center and radius and the point p...
Definition: qgsgeometryutils.cpp:455
QgsPoint::x
double x
Definition: qgspoint.h:69
QgsTriangle
Triangle geometry type.
Definition: qgstriangle.h:33
QgsCircle::asGml2
QDomElement asGml2(QDomDocument &doc, int precision=17, const QString &ns="gml", QgsAbstractGeometry::AxisOrder axisOrder=QgsAbstractGeometry::AxisOrder::XY) const
Returns a GML2 representation of the geometry.
Definition: qgscircle.cpp:478