QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
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
32QgsCircle::QgsCircle( const QgsPoint &center, double radius, double azimuth ) :
33 QgsEllipse( center, radius, radius, azimuth )
34{
35
36}
37
39{
41 const double azimuth = QgsGeometryUtilsBase::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
49static 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
84QgsCircle 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
177QgsCircle 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 = QgsGeometryUtilsBase::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
192static 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 QgsGeometryUtilsBase::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 QgsGeometryUtilsBase::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
278QVector<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 {
302 }
303
304 if ( p2.is3D() )
305 {
307 }
308
309 if ( p3.is3D() )
310 {
312 }
313
314 circles.append( QgsTriangle( p1, p2, p3 ).inscribedCircle() );
315 return circles;
316}
317
318QgsCircle 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
326QgsCircle 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
342int 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
366{
368}
369
370int 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
376int 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
397double QgsCircle::area() const
398{
399 return M_PI * mSemiMajorAxis * mSemiMajorAxis;
400}
401
403{
404 return 2.0 * M_PI * mSemiMajorAxis;
405}
406
407void QgsCircle::setSemiMajorAxis( const double semiMajorAxis )
408{
409 mSemiMajorAxis = std::fabs( semiMajorAxis );
411}
412
413void QgsCircle::setSemiMinorAxis( const double semiMinorAxis )
414{
415 mSemiMajorAxis = std::fabs( semiMinorAxis );
417}
418
419QVector<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
453bool QgsCircle::contains( const QgsPoint &point, double epsilon ) const
454{
455 return ( mCenter.distance( point ) <= mSemiMajorAxis + epsilon );
456}
457
459{
461}
462
463QString 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
478QDomElement 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
486QDomElement QgsCircle::asGml3( QDomDocument &doc, int precision, const QString &ns, const QgsAbstractGeometry::AxisOrder axisOrder ) const
487{
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
Returns true if the geometry is 3D and contains a z-value.
AxisOrder
Axis order for GML generation.
Qgis::WkbType wkbType() const
Returns the WKB type of the geometry.
Circle geometry type.
Definition: qgscircle.h:43
static QgsCircle from2Points(const QgsPoint &pt1, const QgsPoint &pt2)
Constructs a circle by 2 points on the circle.
Definition: qgscircle.cpp:38
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
Returns the radius of the circle.
Definition: qgscircle.h:310
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
void setSemiMinorAxis(double semiMinorAxis) override
Inherited method.
Definition: qgscircle.cpp:413
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
void setSemiMajorAxis(double semiMajorAxis) override
Inherited method.
Definition: qgscircle.cpp:407
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 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())
Constructs a circle by 3 tangents on the circle (aka inscribed circle of a triangle).
Definition: qgscircle.cpp:318
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 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())
Returns an array of circle constructed by 3 tangents on the circle (aka inscribed circle of a triangl...
Definition: qgscircle.cpp:278
static QgsCircle fromExtent(const QgsPoint &pt1, const QgsPoint &pt2)
Constructs a circle by an extent (aka bounding box / QgsRectangle).
Definition: qgscircle.cpp:382
double area() const override
The area of the ellipse.
Definition: qgscircle.cpp:397
static QgsCircle fromCenterDiameter(const QgsPoint &center, double diameter, double azimuth=0)
Constructs a circle by a center point and a diameter.
Definition: qgscircle.cpp:177
static QgsCircle fromCenterPoint(const QgsPoint &center, const QgsPoint &pt1)
Constructs a circle by a center point and another point.
Definition: qgscircle.cpp:182
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
QgsCircularString * toCircularString(bool oriented=false) const
Returns a circular string from the circle.
Definition: qgscircle.cpp:430
double perimeter() const override
The circumference of the ellipse using first approximation of Ramanujan.
Definition: qgscircle.cpp:402
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
static QgsCircle from3Points(const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double epsilon=1E-8)
Constructs a circle by 3 points on the circle.
Definition: qgscircle.cpp:84
QVector< QgsPoint > northQuadrant() const
The four quadrants of the ellipse.
Definition: qgscircle.cpp:419
static QgsCircle minimalCircleFrom3Points(const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double epsilon=1E-8)
Constructs the smallest circle from 3 points.
Definition: qgscircle.cpp:326
Circular string geometry type.
Ellipse geometry type.
Definition: qgsellipse.h:39
QgsPoint mCenter
Definition: qgsellipse.h:251
QgsPoint center() const
Returns the center point.
Definition: qgsellipse.h:120
double semiMajorAxis() const
Returns the semi-major axis.
Definition: qgsellipse.h:126
double mAzimuth
Definition: qgsellipse.h:254
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:252
double azimuth() const
Returns the azimuth.
Definition: qgsellipse.h:138
virtual QVector< QgsPoint > quadrant() const
The four quadrants of the ellipse.
Definition: qgsellipse.cpp:177
virtual bool isEmpty() const
An ellipse is empty if axes are equal to 0.
Definition: qgsellipse.cpp:118
double mSemiMinorAxis
Definition: qgsellipse.h:253
double semiMinorAxis() const
Returns the semi-minor axis.
Definition: qgsellipse.h:132
static double lineAngle(double x1, double y1, double x2, double y2)
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)
Returns the point (pointX, pointY) forming the bisector from segment (aX aY) (bX bY) and segment (bX,...
static int circleCircleIntersections(const QgsPointXY &center1, double radius1, const QgsPointXY &center2, double radius2, QgsPointXY &intersection1, QgsPointXY &intersection2)
Calculates the intersections points between the circle with center center1 and radius radius1 and the...
static int leftOfLine(const QgsPoint &point, const QgsPoint &p1, const QgsPoint &p2)
Returns a value < 0 if the point point is left of the line from p1 -> p2.
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)
Compute the intersection between two segments.
static QgsLineString perpendicularSegment(const QgsPoint &p, const QgsPoint &s1, const QgsPoint &s2)
Create a perpendicular line segment from p to segment [s1, s2].
static QgsPoint midpoint(const QgsPoint &pt1, const QgsPoint &pt2)
Returns a middle point between points pt1 and pt2.
static bool tangentPointAndCircle(const QgsPointXY &center, double radius, const QgsPointXY &p, QgsPointXY &pt1, QgsPointXY &pt2)
Calculates the tangent points between the circle with the specified center and radius and the point p...
static int circleCircleOuterTangents(const QgsPointXY &center1, double radius1, const QgsPointXY &center2, double radius2, QgsPointXY &line1P1, QgsPointXY &line1P2, QgsPointXY &line2P1, QgsPointXY &line2P2)
Calculates the outer tangent points for two circles, centered at center1 and center2 and with radii o...
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 circleCircleInnerTangents(const QgsPointXY &center1, double radius1, const QgsPointXY &center2, double radius2, QgsPointXY &line1P1, QgsPointXY &line1P2, QgsPointXY &line2P1, QgsPointXY &line2P2)
Calculates the inner tangent points for two circles, centered at center1 and center2 and with radii o...
double length() const override
Returns the planar, 2-dimensional length of the geometry.
A class to represent a 2D point.
Definition: qgspointxy.h:60
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:49
void setY(double y)
Sets the point's y-coordinate.
Definition: qgspoint.h:343
bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value.
Definition: qgspoint.cpp:553
QString asWkt(int precision=17) const override
Returns a WKT representation of the geometry.
Definition: qgspoint.cpp:261
void setX(double x)
Sets the point's x-coordinate.
Definition: qgspoint.h:332
Q_GADGET double x
Definition: qgspoint.h:52
double z
Definition: qgspoint.h:54
bool convertTo(Qgis::WkbType type) override
Converts the geometry to a specified type.
Definition: qgspoint.cpp:622
bool isEmpty() const override
Returns true if the geometry is empty.
Definition: qgspoint.cpp:733
double distance(double x, double y) const
Returns the Cartesian 2D distance between this point and a specified x, y coordinate.
Definition: qgspoint.h:393
double m
Definition: qgspoint.h:55
QgsPoint project(double distance, double azimuth, double inclination=90.0) const
Returns a new point which corresponds to this point projected by a specified distance with specified ...
Definition: qgspoint.cpp:701
double y
Definition: qgspoint.h:53
A rectangle specified with double values.
Definition: qgsrectangle.h:42
Triangle geometry type.
Definition: qgstriangle.h:33
static Qgis::WkbType dropZ(Qgis::WkbType type)
Drops the z dimension (if present) for a WKB type and returns the new type.
Definition: qgswkbtypes.h:1127
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Definition: qgis.h:5124
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:5207
QVector< QgsPoint > QgsPointSequence
int precision