QGIS API Documentation  3.22.4-Białowieża (ce8e65e95e)
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 }
bool is3D() const SIP_HOLDGIL
Returns true if the geometry is 3D and contains a z-value.
AxisOrder
Axis order for GML generation.
QgsWkbTypes::Type wkbType() const SIP_HOLDGIL
Returns the WKB type of the geometry.
Circle geometry type.
Definition: qgscircle.h:44
double perimeter() const override SIP_HOLDGIL
The circumference of the ellipse using first approximation of Ramanujan.
Definition: qgscircle.cpp:402
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
double radius() const SIP_HOLDGIL
Returns the radius of the circle.
Definition: qgscircle.h:311
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
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
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
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
void setSemiMinorAxis(double semiMinorAxis) override SIP_HOLDGIL
Inherited method.
Definition: qgscircle.cpp:413
QString toString(int pointPrecision=17, int radiusPrecision=17, int azimuthPrecision=2) const override
returns a string representation of the ellipse.
Definition: qgscircle.cpp:463
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
void setSemiMajorAxis(double semiMajorAxis) override SIP_HOLDGIL
Inherited method.
Definition: qgscircle.cpp:407
static QgsCircle from2Points(const QgsPoint &pt1, const QgsPoint &pt2) SIP_HOLDGIL
Constructs a circle by 2 points on the circle.
Definition: qgscircle.cpp:38
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
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
QgsRectangle boundingBox() const override
Returns the minimal bounding box for the ellipse.
Definition: qgscircle.cpp:458
bool contains(const QgsPoint &point, double epsilon=1E-8) const
Returns true if the circle contains the point.
Definition: qgscircle.cpp:453
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
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
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
QgsCircularString * toCircularString(bool oriented=false) const
Returns a circular string from the circle.
Definition: qgscircle.cpp:430
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
double area() const override SIP_HOLDGIL
The area of the ellipse.
Definition: qgscircle.cpp:397
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
QVector< QgsPoint > northQuadrant() const
The four quadrants of the ellipse.
Definition: qgscircle.cpp:419
Circular string geometry type.
Ellipse geometry type.
Definition: qgsellipse.h:40
QgsPoint mCenter
Definition: qgsellipse.h:252
QgsPoint center() const SIP_HOLDGIL
Returns the center point.
Definition: qgsellipse.h:121
double semiMinorAxis() const SIP_HOLDGIL
Returns the semi-minor axis.
Definition: qgsellipse.h:133
double azimuth() const SIP_HOLDGIL
Returns the azimuth.
Definition: qgsellipse.h:139
double mAzimuth
Definition: qgsellipse.h:255
virtual QgsPointSequence points(unsigned int segments=36) const
Returns a list of points with segmentation from segments.
Definition: qgsellipse.cpp:188
double mSemiMajorAxis
Definition: qgsellipse.h:253
virtual bool isEmpty() const SIP_HOLDGIL
An ellipse is empty if axes are equal to 0.
Definition: qgsellipse.cpp:118
double semiMajorAxis() const SIP_HOLDGIL
Returns the semi-major axis.
Definition: qgsellipse.h:127
virtual QVector< QgsPoint > quadrant() const
The four quadrants of the ellipse.
Definition: qgsellipse.cpp:177
double mSemiMinorAxis
Definition: qgsellipse.h:254
static QgsPoint midpoint(const QgsPoint &pt1, const QgsPoint &pt2) SIP_HOLDGIL
Returns a middle point between points pt1 and pt2.
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...
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.
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.
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,...
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...
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].
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...
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...
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.
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.
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).
double length() const override SIP_HOLDGIL
Returns the planar, 2-dimensional length of the geometry.
A class to represent a 2D point.
Definition: qgspointxy.h:59
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:49
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:343
bool isEmpty() const override SIP_HOLDGIL
Returns true if the geometry is empty.
Definition: qgspoint.cpp:767
bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value.
Definition: qgspoint.cpp:551
void setX(double x) SIP_HOLDGIL
Sets the point's x-coordinate.
Definition: qgspoint.h:280
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
QString asWkt(int precision=17) const override
Returns a WKT representation of the geometry.
Definition: qgspoint.cpp:264
Q_GADGET double x
Definition: qgspoint.h:52
void setY(double y) SIP_HOLDGIL
Sets the point's y-coordinate.
Definition: qgspoint.h:291
bool convertTo(QgsWkbTypes::Type type) override
Converts the geometry to a specified type.
Definition: qgspoint.cpp:620
double z
Definition: qgspoint.h:54
double m
Definition: qgspoint.h:55
double y
Definition: qgspoint.h:53
A rectangle specified with double values.
Definition: qgsrectangle.h:42
Triangle geometry type.
Definition: qgstriangle.h:34
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
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Definition: qgis.h:1198
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:1246
QVector< QgsPoint > QgsPointSequence
int precision