QGIS API Documentation  3.20.0-Odense (decaadbb31)
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 
26  QgsEllipse( QgsPoint(), 0.0, 0.0, 0.0 )
27 {
28 
29 }
30 
31 QgsCircle::QgsCircle( const QgsPoint &center, double radius, double azimuth ) :
32  QgsEllipse( center, radius, radius, azimuth )
33 {
34 
35 }
36 
38 {
40  double azimuth = QgsGeometryUtils::lineAngle( pt1.x(), pt1.y(), pt2.x(), pt2.y() ) * 180.0 / M_PI;
41  double radius = pt1.distance( pt2 ) / 2.0;
42 
44 
45  return QgsCircle( center, radius, azimuth );
46 }
47 
48 static bool isPerpendicular( const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double epsilon )
49 {
50  // check the given point are perpendicular to x or y axis
51 
52  double yDelta_a = pt2.y() - pt1.y();
53  double xDelta_a = pt2.x() - pt1.x();
54  double yDelta_b = pt3.y() - pt2.y();
55  double xDelta_b = pt3.x() - pt2.x();
56 
57  if ( ( std::fabs( xDelta_a ) <= epsilon ) && ( std::fabs( yDelta_b ) <= epsilon ) )
58  {
59  return false;
60  }
61 
62  if ( std::fabs( yDelta_a ) <= epsilon )
63  {
64  return true;
65  }
66  else if ( std::fabs( yDelta_b ) <= epsilon )
67  {
68  return true;
69  }
70  else if ( std::fabs( xDelta_a ) <= epsilon )
71  {
72  return true;
73  }
74  else if ( std::fabs( xDelta_b ) <= epsilon )
75  {
76  return true;
77  }
78 
79  return false;
80 
81 }
82 
83 QgsCircle QgsCircle::from3Points( const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double epsilon )
84 {
85  QgsPoint p1, p2, p3;
86 
87  if ( !isPerpendicular( pt1, pt2, pt3, epsilon ) )
88  {
89  p1 = pt1;
90  p2 = pt2;
91  p3 = pt3;
92  }
93  else if ( !isPerpendicular( pt1, pt3, pt2, epsilon ) )
94  {
95  p1 = pt1;
96  p2 = pt3;
97  p3 = pt2;
98  }
99  else if ( !isPerpendicular( pt2, pt1, pt3, epsilon ) )
100  {
101  p1 = pt2;
102  p2 = pt1;
103  p3 = pt3;
104  }
105  else if ( !isPerpendicular( pt2, pt3, pt1, epsilon ) )
106  {
107  p1 = pt2;
108  p2 = pt3;
109  p3 = pt1;
110  }
111  else if ( !isPerpendicular( pt3, pt2, pt1, epsilon ) )
112  {
113  p1 = pt3;
114  p2 = pt2;
115  p3 = pt1;
116  }
117  else if ( !isPerpendicular( pt3, pt1, pt2, epsilon ) )
118  {
119  p1 = pt3;
120  p2 = pt1;
121  p3 = pt2;
122  }
123  else
124  {
125  return QgsCircle();
126  }
128  double radius = -0.0;
129  // Paul Bourke's algorithm
130  double yDelta_a = p2.y() - p1.y();
131  double xDelta_a = p2.x() - p1.x();
132  double yDelta_b = p3.y() - p2.y();
133  double xDelta_b = p3.x() - p2.x();
134 
135  if ( qgsDoubleNear( xDelta_a, 0.0, epsilon ) || qgsDoubleNear( xDelta_b, 0.0, epsilon ) )
136  {
137  return QgsCircle();
138  }
139 
140  double aSlope = yDelta_a / xDelta_a;
141  double bSlope = yDelta_b / xDelta_b;
142 
143  // set z coordinate for center
145 
146  if ( ( std::fabs( xDelta_a ) <= epsilon ) && ( std::fabs( yDelta_b ) <= epsilon ) )
147  {
148  center.setX( 0.5 * ( p2.x() + p3.x() ) );
149  center.setY( 0.5 * ( p1.y() + p2.y() ) );
150  radius = center.distance( pt1 );
151 
152  return QgsCircle( center, radius );
153  }
154 
155  if ( std::fabs( aSlope - bSlope ) <= epsilon )
156  {
157  return QgsCircle();
158  }
159 
160  center.setX(
161  ( aSlope * bSlope * ( p1.y() - p3.y() ) +
162  bSlope * ( p1.x() + p2.x() ) -
163  aSlope * ( p2.x() + p3.x() ) ) /
164  ( 2.0 * ( bSlope - aSlope ) )
165  );
166  center.setY(
167  -1.0 * ( center.x() - ( p1.x() + p2.x() ) / 2.0 ) /
168  aSlope + ( p1.y() + p2.y() ) / 2.0
169  );
170 
171  radius = center.distance( p1 );
172 
173  return QgsCircle( center, radius );
174 }
175 
176 QgsCircle QgsCircle::fromCenterDiameter( const QgsPoint &center, double diameter, double azimuth )
177 {
178  return QgsCircle( center, diameter / 2.0, azimuth );
179 }
180 
182 {
183  double azimuth = QgsGeometryUtils::lineAngle( center.x(), center.y(), pt1.x(), pt1.y() ) * 180.0 / M_PI;
184 
185  QgsPoint centerPt( center );
187 
188  return QgsCircle( centerPt, centerPt.distance( pt1 ), azimuth );
189 }
190 
191 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, QgsPoint pos, double epsilon )
192 {
193  const double radius = QgsGeometryUtils::perpendicularSegment( pt1_par2, pt1_par1, pt2_par1 ).length() / 2.0;
194 
195  bool isInter;
196  QgsPoint ptInter;
197  QVector<QgsCircle> circles;
198 
199  QgsPoint ptInter_par1line1, ptInter_par2line1;
200  double angle1, angle2;
201  double x, y;
202  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 );
203  ptInter_par1line1.setX( x );
204  ptInter_par1line1.setY( y );
205 
206  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 );
207  ptInter_par2line1.setX( x );
208  ptInter_par2line1.setY( y );
209 
210  QgsPoint center;
211  QgsGeometryUtils::segmentIntersection( ptInter_par1line1, ptInter_par1line1.project( 1.0, angle1 ), ptInter_par2line1, ptInter_par2line1.project( 1.0, angle2 ), center, isInter, epsilon, true );
212  if ( isInter )
213  {
214  if ( !pos.isEmpty() )
215  {
216  if ( QgsGeometryUtils::leftOfLine( center, pt1_line1, pt2_line1 ) == QgsGeometryUtils::leftOfLine( pos, pt1_line1, pt2_line1 ) )
217  {
218  circles.append( QgsCircle( center, radius ) );
219  }
220  }
221  else
222  {
223  circles.append( QgsCircle( center, radius ) );
224  }
225  }
226 
227  QgsGeometryUtils::segmentIntersection( ptInter_par1line1, ptInter_par1line1.project( 1.0, angle1 ), ptInter_par2line1, ptInter_par2line1.project( 1.0, angle2 + 90.0 ), center, isInter, epsilon, true );
228  if ( isInter )
229  {
230  if ( !pos.isEmpty() )
231  {
232  if ( QgsGeometryUtils::leftOfLine( center, pt1_line1, pt2_line1 ) == QgsGeometryUtils::leftOfLine( pos, pt1_line1, pt2_line1 ) )
233  {
234  circles.append( QgsCircle( center, radius ) );
235  }
236  }
237  else
238  {
239  circles.append( QgsCircle( center, radius ) );
240  }
241  }
242 
243  QgsGeometryUtils::segmentIntersection( ptInter_par1line1, ptInter_par1line1.project( 1.0, angle1 + 90.0 ), ptInter_par2line1, ptInter_par2line1.project( 1.0, angle2 ), center, isInter, epsilon, true );
244  if ( isInter && !circles.contains( QgsCircle( center, radius ) ) )
245  {
246  if ( !pos.isEmpty() )
247  {
248  if ( QgsGeometryUtils::leftOfLine( center, pt1_line1, pt2_line1 ) == QgsGeometryUtils::leftOfLine( pos, pt1_line1, pt2_line1 ) )
249  {
250  circles.append( QgsCircle( center, radius ) );
251  }
252  }
253  else
254  {
255  circles.append( QgsCircle( center, radius ) );
256  }
257  }
258  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 );
259  if ( isInter && !circles.contains( QgsCircle( center, radius ) ) )
260  {
261  if ( !pos.isEmpty() )
262  {
263  if ( QgsGeometryUtils::leftOfLine( center, pt1_line1, pt2_line1 ) == QgsGeometryUtils::leftOfLine( pos, pt1_line1, pt2_line1 ) )
264  {
265  circles.append( QgsCircle( center, radius ) );
266  }
267  }
268  else
269  {
270  circles.append( QgsCircle( center, radius ) );
271  }
272  }
273 
274  return circles;
275 }
276 
277 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, QgsPoint pos )
278 {
279  QgsPoint p1, p2, p3;
280  bool isIntersect_tg1tg2 = false;
281  bool isIntersect_tg1tg3 = false;
282  bool isIntersect_tg2tg3 = false;
283  QgsGeometryUtils::segmentIntersection( pt1_tg1, pt2_tg1, pt1_tg2, pt2_tg2, p1, isIntersect_tg1tg2, epsilon );
284  QgsGeometryUtils::segmentIntersection( pt1_tg1, pt2_tg1, pt1_tg3, pt2_tg3, p2, isIntersect_tg1tg3, epsilon );
285  QgsGeometryUtils::segmentIntersection( pt1_tg2, pt2_tg2, pt1_tg3, pt2_tg3, p3, isIntersect_tg2tg3, epsilon );
286 
287  QVector<QgsCircle> circles;
288  if ( !isIntersect_tg1tg2 && !isIntersect_tg2tg3 ) // three lines are parallels
289  return circles;
290 
291  if ( !isIntersect_tg1tg2 )
292  return from2ParallelsLine( pt1_tg1, pt2_tg1, pt1_tg2, pt2_tg2, pt1_tg3, pt2_tg3, pos, epsilon );
293  else if ( !isIntersect_tg1tg3 )
294  return from2ParallelsLine( pt1_tg1, pt2_tg1, pt1_tg3, pt2_tg3, pt1_tg2, pt2_tg2, pos, epsilon );
295  else if ( !isIntersect_tg2tg3 )
296  return from2ParallelsLine( pt1_tg2, pt2_tg2, pt1_tg3, pt2_tg3, pt1_tg1, pt1_tg1, pos, epsilon );
297 
298  if ( p1.is3D() )
299  {
300  p1.convertTo( QgsWkbTypes::dropZ( p1.wkbType() ) );
301  }
302 
303  if ( p2.is3D() )
304  {
305  p2.convertTo( QgsWkbTypes::dropZ( p2.wkbType() ) );
306  }
307 
308  if ( p3.is3D() )
309  {
310  p3.convertTo( QgsWkbTypes::dropZ( p3.wkbType() ) );
311  }
312 
313  circles.append( QgsTriangle( p1, p2, p3 ).inscribedCircle() );
314  return circles;
315 }
316 
317 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, QgsPoint pos )
318 {
319  const QVector<QgsCircle> circles = from3TangentsMulti( pt1_tg1, pt2_tg1, pt1_tg2, pt2_tg2, pt1_tg3, pt2_tg3, epsilon, pos );
320  if ( circles.length() != 1 )
321  return QgsCircle();
322  return circles.at( 0 );
323 }
324 
325 QgsCircle QgsCircle::minimalCircleFrom3Points( const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double epsilon )
326 {
327  double l1 = pt2.distance( pt3 );
328  double l2 = pt3.distance( pt1 );
329  double l3 = pt1.distance( pt2 );
330 
331  if ( ( l1 * l1 ) - ( l2 * l2 + l3 * l3 ) >= epsilon )
332  return QgsCircle().from2Points( pt2, pt3 );
333  else if ( ( l2 * l2 ) - ( l1 * l1 + l3 * l3 ) >= epsilon )
334  return QgsCircle().from2Points( pt3, pt1 );
335  else if ( ( l3 * l3 ) - ( l1 * l1 + l2 * l2 ) >= epsilon )
336  return QgsCircle().from2Points( pt1, pt2 );
337  else
338  return QgsCircle().from3Points( pt1, pt2, pt3, epsilon );
339 }
340 
341 int QgsCircle::intersections( const QgsCircle &other, QgsPoint &intersection1, QgsPoint &intersection2, bool useZ ) const
342 {
343  if ( useZ && mCenter.is3D() && other.center().is3D() && !qgsDoubleNear( mCenter.z(), other.center().z() ) )
344  return 0;
345 
346  QgsPointXY int1, int2;
347 
349  QgsPointXY( other.center() ), other.radius(),
350  int1, int2 );
351  if ( res == 0 )
352  return 0;
353 
354  intersection1 = QgsPoint( int1 );
355  intersection2 = QgsPoint( int2 );
356  if ( useZ && mCenter.is3D() )
357  {
358  intersection1.addZValue( mCenter.z() );
359  intersection2.addZValue( mCenter.z() );
360  }
361  return res;
362 }
363 
364 bool QgsCircle::tangentToPoint( const QgsPointXY &p, QgsPointXY &pt1, QgsPointXY &pt2 ) const
365 {
367 }
368 
369 int QgsCircle::outerTangents( const QgsCircle &other, QgsPointXY &line1P1, QgsPointXY &line1P2, QgsPointXY &line2P1, QgsPointXY &line2P2 ) const
370 {
372  QgsPointXY( other.center() ), other.radius(), line1P1, line1P2, line2P1, line2P2 );
373 }
374 
375 int QgsCircle::innerTangents( const QgsCircle &other, QgsPointXY &line1P1, QgsPointXY &line1P2, QgsPointXY &line2P1, QgsPointXY &line2P2 ) const
376 {
378  QgsPointXY( other.center() ), other.radius(), line1P1, line1P2, line2P1, line2P2 );
379 }
380 
382 {
383  double delta_x = std::fabs( pt1.x() - pt2.x() );
384  double delta_y = std::fabs( pt1.x() - pt2.y() );
385  if ( !qgsDoubleNear( delta_x, delta_y ) )
386  {
387  return QgsCircle();
388  }
389 
392 
393  return QgsCircle( center, delta_x / 2.0, 0 );
394 }
395 
396 double QgsCircle::area() const
397 {
398  return M_PI * mSemiMajorAxis * mSemiMajorAxis;
399 }
400 
401 double QgsCircle::perimeter() const
402 {
403  return 2.0 * M_PI * mSemiMajorAxis;
404 }
405 
406 void QgsCircle::setSemiMajorAxis( const double semiMajorAxis )
407 {
408  mSemiMajorAxis = std::fabs( semiMajorAxis );
410 }
411 
412 void QgsCircle::setSemiMinorAxis( const double semiMinorAxis )
413 {
414  mSemiMajorAxis = std::fabs( semiMinorAxis );
416 }
417 
418 QVector<QgsPoint> QgsCircle::northQuadrant() const
419 {
420  QVector<QgsPoint> quad;
421  quad.append( QgsPoint( mCenter.x(), mCenter.y() + mSemiMajorAxis, mCenter.z() ) );
422  quad.append( QgsPoint( mCenter.x() + mSemiMajorAxis, mCenter.y(), mCenter.z() ) );
423  quad.append( QgsPoint( mCenter.x(), mCenter.y() - mSemiMajorAxis, mCenter.z() ) );
424  quad.append( QgsPoint( mCenter.x() - mSemiMajorAxis, mCenter.y(), mCenter.z() ) );
425 
426  return quad;
427 }
428 
430 {
431  std::unique_ptr<QgsCircularString> circString( new QgsCircularString() );
433  QVector<QgsPoint> quad;
434  if ( oriented )
435  {
436  quad = quadrant();
437  }
438  else
439  {
440  quad = northQuadrant();
441  }
442  quad.append( quad.at( 0 ) );
443  for ( QVector<QgsPoint>::const_iterator it = quad.constBegin(); it != quad.constEnd(); ++it )
444  {
445  points.append( *it );
446  }
447  circString->setPoints( points );
448 
449  return circString.release();
450 }
451 
452 bool QgsCircle::contains( const QgsPoint &point, double epsilon ) const
453 {
454  return ( mCenter.distance( point ) <= mSemiMajorAxis + epsilon );
455 }
456 
458 {
460 }
461 
462 QString QgsCircle::toString( int pointPrecision, int radiusPrecision, int azimuthPrecision ) const
463 {
464  QString rep;
465  if ( isEmpty() )
466  rep = QStringLiteral( "Empty" );
467  else
468  rep = QStringLiteral( "Circle (Center: %1, Radius: %2, Azimuth: %3)" )
469  .arg( mCenter.asWkt( pointPrecision ), 0, 's' )
470  .arg( qgsDoubleToString( mSemiMajorAxis, radiusPrecision ), 0, 'f' )
471  .arg( qgsDoubleToString( mAzimuth, azimuthPrecision ), 0, 'f' );
472 
473  return rep;
474 
475 }
476 
477 QDomElement QgsCircle::asGml2( QDomDocument &doc, int precision, const QString &ns, const QgsAbstractGeometry::AxisOrder axisOrder ) const
478 {
479  // Gml2 does not support curve. It will be converted to a linestring via CircularString
480  std::unique_ptr< QgsCircularString > circularString( toCircularString() );
481  QDomElement gml = circularString->asGml2( doc, precision, ns, axisOrder );
482  return gml;
483 }
484 
485 QDomElement QgsCircle::asGml3( QDomDocument &doc, int precision, const QString &ns, const QgsAbstractGeometry::AxisOrder axisOrder ) const
486 {
487  QgsPointSequence pts;
488  pts << northQuadrant().at( 0 ) << northQuadrant().at( 1 ) << northQuadrant().at( 2 );
489 
490  QDomElement elemCircle = doc.createElementNS( ns, QStringLiteral( "Circle" ) );
491 
492  if ( isEmpty() )
493  return elemCircle;
494 
495  elemCircle.appendChild( QgsGeometryUtils::pointsToGML3( pts, doc, precision, ns, mCenter.is3D(), axisOrder ) );
496  return elemCircle;
497 }
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:401
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:341
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:485
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:375
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:369
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:83
void setSemiMinorAxis(double semiMinorAxis) override SIP_HOLDGIL
Inherited method.
Definition: qgscircle.cpp:412
QString toString(int pointPrecision=17, int radiusPrecision=17, int azimuthPrecision=2) const override
returns a string representation of the ellipse.
Definition: qgscircle.cpp:462
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:176
void setSemiMajorAxis(double semiMajorAxis) override SIP_HOLDGIL
Inherited method.
Definition: qgscircle.cpp:406
static QgsCircle from2Points(const QgsPoint &pt1, const QgsPoint &pt2) SIP_HOLDGIL
Constructs a circle by 2 points on the circle.
Definition: qgscircle.cpp:37
static QgsCircle fromCenterPoint(const QgsPoint &center, const QgsPoint &pt1) SIP_HOLDGIL
Constructs a circle by a center point and another point.
Definition: qgscircle.cpp:181
QgsRectangle boundingBox() const override
Returns the minimal bounding box for the ellipse.
Definition: qgscircle.cpp:457
bool contains(const QgsPoint &point, double epsilon=1E-8) const
Returns true if the circle contains the point.
Definition: qgscircle.cpp:452
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:325
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, 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:277
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:477
static QgsCircle fromExtent(const QgsPoint &pt1, const QgsPoint &pt2) SIP_HOLDGIL
Constructs a circle by an extent (aka bounding box / QgsRectangle).
Definition: qgscircle.cpp:381
QgsCircularString * toCircularString(bool oriented=false) const
Returns a circular string from the circle.
Definition: qgscircle.cpp:429
bool tangentToPoint(const QgsPointXY &p, QgsPointXY &pt1, QgsPointXY &pt2) const
Calculates the tangent points between this circle and the point p.
Definition: qgscircle.cpp:364
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, QgsPoint pos=QgsPoint()) SIP_HOLDGIL
Constructs a circle by 3 tangents on the circle (aka inscribed circle of a triangle).
Definition: qgscircle.cpp:317
double area() const override SIP_HOLDGIL
The area of the ellipse.
Definition: qgscircle.cpp:396
QVector< QgsPoint > northQuadrant() const
The four quadrants of the ellipse.
Definition: qgscircle.cpp:418
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 int circleCircleIntersections(QgsPointXY center1, double radius1, 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 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 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 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:1207
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Definition: qgis.h:550
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:598
QVector< QgsPoint > QgsPointSequence
int precision