QGIS API Documentation  3.21.0-Master (56b4176581)
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  const double azimuth = QgsGeometryUtils::lineAngle( pt1.x(), pt1.y(), pt2.x(), pt2.y() ) * 180.0 / M_PI;
41  const 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  const double yDelta_a = pt2.y() - pt1.y();
53  const double xDelta_a = pt2.x() - pt1.x();
54  const double yDelta_b = pt3.y() - pt2.y();
55  const 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  const double yDelta_a = p2.y() - p1.y();
131  const double xDelta_a = p2.x() - p1.x();
132  const double yDelta_b = p3.y() - p2.y();
133  const 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  const double aSlope = yDelta_a / xDelta_a;
141  const double bSlope = yDelta_b / xDelta_b;
142
143  // set z and m 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  const 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  const 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  const double l1 = pt2.distance( pt3 );
328  const double l2 = pt3.distance( pt1 );
329  const 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  const double delta_x = std::fabs( pt1.x() - pt2.x() );
384  const 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 {
421  quad.append( QgsPoint( mCenter.x(), mCenter.y() + mSemiMajorAxis, mCenter.z(), mCenter.m() ) );
422  quad.append( QgsPoint( mCenter.x() + mSemiMajorAxis, mCenter.y(), mCenter.z(), mCenter.m() ) );
423  quad.append( QgsPoint( mCenter.x(), mCenter.y() - mSemiMajorAxis, mCenter.z(), mCenter.m() ) );
424  quad.append( QgsPoint( mCenter.x() - mSemiMajorAxis, mCenter.y(), mCenter.z(), mCenter.m() ) );
425
427 }
428
430 {
431  std::unique_ptr<QgsCircularString> circString( new QgsCircularString() );
434  if ( oriented )
435  {
437  }
438  else
439  {
441  }
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  const 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
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:1207
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Definition: qgis.h:1085
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:1133
QVector< QgsPoint > QgsPointSequence
int precision