QGIS API Documentation 3.99.0-Master (8e76e220402)
Loading...
Searching...
No Matches
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 : lituus at free dot fr
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
20#include <memory>
21#include <utility>
22
23#include "qgsgeometryutils.h"
24#include "qgslinestring.h"
25#include "qgstriangle.h"
26
27#include <QString>
28
29using namespace Qt::StringLiterals;
30
32 : QgsEllipse( QgsPoint(), 0.0, 0.0, 0.0 )
33{
34}
35
40
42{
44 const double azimuth = QgsGeometryUtilsBase::lineAngle( pt1.x(), pt1.y(), pt2.x(), pt2.y() ) * 180.0 / M_PI;
45 const double radius = pt1.distance( pt2 ) / 2.0;
46
48
49 return QgsCircle( center, radius, azimuth );
50}
51
52static bool isPerpendicular( const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double epsilon )
53{
54 // check the given point are perpendicular to x or y axis
55
56 const double yDelta_a = pt2.y() - pt1.y();
57 const double xDelta_a = pt2.x() - pt1.x();
58 const double yDelta_b = pt3.y() - pt2.y();
59 const double xDelta_b = pt3.x() - pt2.x();
60
61 if ( ( std::fabs( xDelta_a ) <= epsilon ) && ( std::fabs( yDelta_b ) <= epsilon ) )
62 {
63 return false;
64 }
65
66 if ( std::fabs( yDelta_a ) <= epsilon )
67 {
68 return true;
69 }
70 else if ( std::fabs( yDelta_b ) <= epsilon )
71 {
72 return true;
73 }
74 else if ( std::fabs( xDelta_a ) <= epsilon )
75 {
76 return true;
77 }
78 else if ( std::fabs( xDelta_b ) <= epsilon )
79 {
80 return true;
81 }
82
83 return false;
84}
85
86QgsCircle QgsCircle::from3Points( const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double epsilon )
87{
88 QgsPoint p1, p2, p3;
89
90 if ( !isPerpendicular( pt1, pt2, pt3, epsilon ) )
91 {
92 p1 = pt1;
93 p2 = pt2;
94 p3 = pt3;
95 }
96 else if ( !isPerpendicular( pt1, pt3, pt2, epsilon ) )
97 {
98 p1 = pt1;
99 p2 = pt3;
100 p3 = pt2;
101 }
102 else if ( !isPerpendicular( pt2, pt1, pt3, epsilon ) )
103 {
104 p1 = pt2;
105 p2 = pt1;
106 p3 = pt3;
107 }
108 else if ( !isPerpendicular( pt2, pt3, pt1, epsilon ) )
109 {
110 p1 = pt2;
111 p2 = pt3;
112 p3 = pt1;
113 }
114 else if ( !isPerpendicular( pt3, pt2, pt1, epsilon ) )
115 {
116 p1 = pt3;
117 p2 = pt2;
118 p3 = pt1;
119 }
120 else if ( !isPerpendicular( pt3, pt1, pt2, epsilon ) )
121 {
122 p1 = pt3;
123 p2 = pt1;
124 p3 = pt2;
125 }
126 else
127 {
128 return QgsCircle();
129 }
131 double radius = -0.0;
132 // Paul Bourke's algorithm
133 const double yDelta_a = p2.y() - p1.y();
134 const double xDelta_a = p2.x() - p1.x();
135 const double yDelta_b = p3.y() - p2.y();
136 const double xDelta_b = p3.x() - p2.x();
137
138 if ( qgsDoubleNear( xDelta_a, 0.0, epsilon ) || qgsDoubleNear( xDelta_b, 0.0, epsilon ) )
139 {
140 return QgsCircle();
141 }
142
143 const double aSlope = yDelta_a / xDelta_a;
144 const double bSlope = yDelta_b / xDelta_b;
145
146 // set z and m coordinate for center
148
149 if ( ( std::fabs( xDelta_a ) <= epsilon ) && ( std::fabs( yDelta_b ) <= epsilon ) )
150 {
151 center.setX( 0.5 * ( p2.x() + p3.x() ) );
152 center.setY( 0.5 * ( p1.y() + p2.y() ) );
153 radius = center.distance( pt1 );
154
155 return QgsCircle( center, radius );
156 }
157
158 if ( std::fabs( aSlope - bSlope ) <= epsilon )
159 {
160 return QgsCircle();
161 }
162
163 center.setX(
164 ( aSlope * bSlope * ( p1.y() - p3.y() ) + bSlope * ( p1.x() + p2.x() ) - aSlope * ( p2.x() + p3.x() ) ) / ( 2.0 * ( bSlope - aSlope ) )
165 );
166 center.setY(
167 -1.0 * ( center.x() - ( p1.x() + p2.x() ) / 2.0 ) / aSlope + ( p1.y() + p2.y() ) / 2.0
168 );
169
170 radius = center.distance( p1 );
171
172 return QgsCircle( center, radius );
173}
174
176{
177 return QgsCircle( center, diameter / 2.0, azimuth );
178}
179
180QgsCircle QgsCircle::fromCenterPoint( const QgsPoint &center, const QgsPoint &pt1 ) // cppcheck-suppress duplInheritedMember
181{
182 const double azimuth = QgsGeometryUtilsBase::lineAngle( center.x(), center.y(), pt1.x(), pt1.y() ) * 180.0 / M_PI;
183
184 QgsPoint centerPt( center );
186
187 return QgsCircle( centerPt, centerPt.distance( pt1 ), azimuth );
188}
189
190static 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 )
191{
192 const double radius = QgsGeometryUtils::perpendicularSegment( pt1_par2, pt1_par1, pt2_par1 ).length() / 2.0;
193
194 bool isInter;
195 const QgsPoint ptInter;
196 QVector<QgsCircle> circles;
197
198 QgsPoint ptInter_par1line1, ptInter_par2line1;
199 double angle1, angle2;
200 double x, y;
201 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 );
202 ptInter_par1line1.setX( x );
203 ptInter_par1line1.setY( y );
204
205 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 );
206 ptInter_par2line1.setX( x );
207 ptInter_par2line1.setY( y );
208
209 QgsPoint center;
210 QgsGeometryUtils::segmentIntersection( ptInter_par1line1, ptInter_par1line1.project( 1.0, angle1 ), ptInter_par2line1, ptInter_par2line1.project( 1.0, angle2 ), center, isInter, epsilon, true );
211 if ( isInter )
212 {
213 if ( !pos.isEmpty() )
214 {
215 if ( QgsGeometryUtils::leftOfLine( center, pt1_line1, pt2_line1 ) == QgsGeometryUtils::leftOfLine( pos, pt1_line1, pt2_line1 ) )
216 {
217 circles.append( QgsCircle( center, radius ) );
218 }
219 }
220 else
221 {
222 circles.append( QgsCircle( center, radius ) );
223 }
224 }
225
226 QgsGeometryUtils::segmentIntersection( ptInter_par1line1, ptInter_par1line1.project( 1.0, angle1 ), ptInter_par2line1, ptInter_par2line1.project( 1.0, angle2 + 90.0 ), center, isInter, epsilon, true );
227 if ( isInter )
228 {
229 if ( !pos.isEmpty() )
230 {
231 if ( QgsGeometryUtils::leftOfLine( center, pt1_line1, pt2_line1 ) == QgsGeometryUtils::leftOfLine( pos, pt1_line1, pt2_line1 ) )
232 {
233 circles.append( QgsCircle( center, radius ) );
234 }
235 }
236 else
237 {
238 circles.append( QgsCircle( center, radius ) );
239 }
240 }
241
242 QgsGeometryUtils::segmentIntersection( ptInter_par1line1, ptInter_par1line1.project( 1.0, angle1 + 90.0 ), ptInter_par2line1, ptInter_par2line1.project( 1.0, angle2 ), center, isInter, epsilon, true );
243 if ( isInter && !circles.contains( QgsCircle( center, radius ) ) )
244 {
245 if ( !pos.isEmpty() )
246 {
247 if ( QgsGeometryUtils::leftOfLine( center, pt1_line1, pt2_line1 ) == QgsGeometryUtils::leftOfLine( pos, pt1_line1, pt2_line1 ) )
248 {
249 circles.append( QgsCircle( center, radius ) );
250 }
251 }
252 else
253 {
254 circles.append( QgsCircle( center, radius ) );
255 }
256 }
257 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 );
258 if ( isInter && !circles.contains( QgsCircle( center, radius ) ) )
259 {
260 if ( !pos.isEmpty() )
261 {
262 if ( QgsGeometryUtils::leftOfLine( center, pt1_line1, pt2_line1 ) == QgsGeometryUtils::leftOfLine( pos, pt1_line1, pt2_line1 ) )
263 {
264 circles.append( QgsCircle( center, radius ) );
265 }
266 }
267 else
268 {
269 circles.append( QgsCircle( center, radius ) );
270 }
271 }
272
273 return circles;
274}
275
276QVector<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 )
277{
278 QgsPoint p1, p2, p3;
279 bool isIntersect_tg1tg2 = false;
280 bool isIntersect_tg1tg3 = false;
281 bool isIntersect_tg2tg3 = false;
282 QgsGeometryUtils::segmentIntersection( pt1_tg1, pt2_tg1, pt1_tg2, pt2_tg2, p1, isIntersect_tg1tg2, epsilon );
283 QgsGeometryUtils::segmentIntersection( pt1_tg1, pt2_tg1, pt1_tg3, pt2_tg3, p2, isIntersect_tg1tg3, epsilon );
284 QgsGeometryUtils::segmentIntersection( pt1_tg2, pt2_tg2, pt1_tg3, pt2_tg3, p3, isIntersect_tg2tg3, epsilon );
285
286 QVector<QgsCircle> circles;
287 if ( !isIntersect_tg1tg2 && !isIntersect_tg2tg3 ) // three lines are parallels
288 return circles;
289
290 if ( !isIntersect_tg1tg2 )
291 return from2ParallelsLine( pt1_tg1, pt2_tg1, pt1_tg2, pt2_tg2, pt1_tg3, pt2_tg3, pos, epsilon );
292 else if ( !isIntersect_tg1tg3 )
293 return from2ParallelsLine( pt1_tg1, pt2_tg1, pt1_tg3, pt2_tg3, pt1_tg2, pt2_tg2, pos, epsilon );
294 else if ( !isIntersect_tg2tg3 )
295 return from2ParallelsLine( pt1_tg2, pt2_tg2, pt1_tg3, pt2_tg3, pt1_tg1, pt1_tg1, pos, epsilon );
296
297 if ( p1.is3D() )
298 {
300 }
301
302 if ( p2.is3D() )
303 {
305 }
306
307 if ( p3.is3D() )
308 {
310 }
311
312 circles.append( QgsTriangle( p1, p2, p3 ).inscribedCircle() );
313 return circles;
314}
315
316QgsCircle 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 )
317{
318 const QVector<QgsCircle> circles = from3TangentsMulti( pt1_tg1, pt2_tg1, pt1_tg2, pt2_tg2, pt1_tg3, pt2_tg3, epsilon, pos );
319 if ( circles.length() != 1 )
320 return QgsCircle();
321 return circles.at( 0 );
322}
323
324QgsCircle QgsCircle::minimalCircleFrom3Points( const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double epsilon )
325{
326 const double l1 = pt2.distance( pt3 );
327 const double l2 = pt3.distance( pt1 );
328 const double l3 = pt1.distance( pt2 );
329
330 if ( ( l1 * l1 ) - ( l2 * l2 + l3 * l3 ) >= epsilon )
331 return QgsCircle().from2Points( pt2, pt3 );
332 else if ( ( l2 * l2 ) - ( l1 * l1 + l3 * l3 ) >= epsilon )
333 return QgsCircle().from2Points( pt3, pt1 );
334 else if ( ( l3 * l3 ) - ( l1 * l1 + l2 * l2 ) >= epsilon )
335 return QgsCircle().from2Points( pt1, pt2 );
336 else
337 return QgsCircle().from3Points( pt1, pt2, pt3, epsilon );
338}
339
340int QgsCircle::intersections( const QgsCircle &other, QgsPoint &intersection1, QgsPoint &intersection2, bool useZ ) const
341{
342 if ( useZ && mCenter.is3D() && other.center().is3D() && !qgsDoubleNear( mCenter.z(), other.center().z() ) )
343 return 0;
344
345 QgsPointXY int1, int2;
346
347 const int res = QgsGeometryUtils::circleCircleIntersections( QgsPointXY( mCenter ), radius(), QgsPointXY( other.center() ), other.radius(), int1, int2 );
348 if ( res == 0 )
349 return 0;
350
351 intersection1 = QgsPoint( int1 );
352 intersection2 = QgsPoint( int2 );
353 if ( useZ && mCenter.is3D() )
354 {
355 intersection1.addZValue( mCenter.z() );
356 intersection2.addZValue( mCenter.z() );
357 }
358 return res;
359}
360
362{
364}
365
366int QgsCircle::outerTangents( const QgsCircle &other, QgsPointXY &line1P1, QgsPointXY &line1P2, QgsPointXY &line2P1, QgsPointXY &line2P2 ) const
367{
368 return QgsGeometryUtils::circleCircleOuterTangents( QgsPointXY( mCenter ), radius(), QgsPointXY( other.center() ), other.radius(), line1P1, line1P2, line2P1, line2P2 );
369}
370
371int QgsCircle::innerTangents( const QgsCircle &other, QgsPointXY &line1P1, QgsPointXY &line1P2, QgsPointXY &line2P1, QgsPointXY &line2P2 ) const
372{
373 return QgsGeometryUtils::circleCircleInnerTangents( QgsPointXY( mCenter ), radius(), QgsPointXY( other.center() ), other.radius(), line1P1, line1P2, line2P1, line2P2 );
374}
375
376QgsCircle QgsCircle::fromExtent( const QgsPoint &pt1, const QgsPoint &pt2 ) // cppcheck-suppress duplInheritedMember
377{
378 const double delta_x = std::fabs( pt1.x() - pt2.x() );
379 const double delta_y = std::fabs( pt1.x() - pt2.y() );
380 if ( !qgsDoubleNear( delta_x, delta_y ) )
381 {
382 return QgsCircle();
383 }
384
387
388 return QgsCircle( center, delta_x / 2.0, 0 );
389}
390
391double QgsCircle::area() const
392{
393 return M_PI * mSemiMajorAxis * mSemiMajorAxis;
394}
395
397{
398 return 2.0 * M_PI * mSemiMajorAxis;
399}
400
406
412
413QVector<QgsPoint> QgsCircle::northQuadrant() const
414{
415 QVector<QgsPoint> quad;
416 quad.append( QgsPoint( mCenter.x(), mCenter.y() + mSemiMajorAxis, mCenter.z(), mCenter.m() ) );
417 quad.append( QgsPoint( mCenter.x() + mSemiMajorAxis, mCenter.y(), mCenter.z(), mCenter.m() ) );
418 quad.append( QgsPoint( mCenter.x(), mCenter.y() - mSemiMajorAxis, mCenter.z(), mCenter.m() ) );
419 quad.append( QgsPoint( mCenter.x() - mSemiMajorAxis, mCenter.y(), mCenter.z(), mCenter.m() ) );
420
421 return quad;
422}
423
425{
426 auto circString = std::make_unique<QgsCircularString>();
428 QVector<QgsPoint> quad;
429 if ( oriented )
430 {
431 quad = quadrant();
432 }
433 else
434 {
435 quad = northQuadrant();
436 }
437 quad.append( quad.at( 0 ) );
438 for ( QVector<QgsPoint>::const_iterator it = quad.constBegin(); it != quad.constEnd(); ++it )
439 {
440 points.append( *it );
441 }
442 circString->setPoints( points );
443
444 return circString.release();
445}
446
447bool QgsCircle::contains( const QgsPoint &point, double epsilon ) const
448{
449 return ( mCenter.distance( point ) <= mSemiMajorAxis + epsilon );
450}
451
456
457QString QgsCircle::toString( int pointPrecision, int radiusPrecision, int azimuthPrecision ) const
458{
459 QString rep;
460 if ( isEmpty() )
461 rep = u"Empty"_s;
462 else
463 rep = u"Circle (Center: %1, Radius: %2, Azimuth: %3)"_s
464 .arg( mCenter.asWkt( pointPrecision ), 0, 's' )
465 .arg( qgsDoubleToString( mSemiMajorAxis, radiusPrecision ), 0, 'f' )
466 .arg( qgsDoubleToString( mAzimuth, azimuthPrecision ), 0, 'f' );
467
468 return rep;
469}
470
471QDomElement QgsCircle::asGml2( QDomDocument &doc, int precision, const QString &ns, const QgsAbstractGeometry::AxisOrder axisOrder ) const
472{
473 // Gml2 does not support curve. It will be converted to a linestring via CircularString
474 std::unique_ptr< QgsCircularString > circularString( toCircularString() );
475 const QDomElement gml = circularString->asGml2( doc, precision, ns, axisOrder );
476 return gml;
477}
478
479QDomElement QgsCircle::asGml3( QDomDocument &doc, int precision, const QString &ns, const QgsAbstractGeometry::AxisOrder axisOrder ) const
480{
482 pts << northQuadrant().at( 0 ) << northQuadrant().at( 1 ) << northQuadrant().at( 2 );
483
484 QDomElement elemCircle = doc.createElementNS( ns, u"Circle"_s );
485
486 if ( isEmpty() )
487 return elemCircle;
488
489 elemCircle.appendChild( QgsGeometryUtils::pointsToGML3( pts, doc, precision, ns, mCenter.is3D(), axisOrder ) );
490 return elemCircle;
491}
492
493int QgsCircle::calculateSegments( double radius, double parameter, int minSegments, Qgis::SegmentCalculationMethod method )
494{
495 if ( radius <= 0.0 )
496 {
497 return minSegments;
498 }
499
500 if ( parameter <= 0.0 )
501 {
502 parameter = 0.01;
503 }
504
505 if ( minSegments < 3 )
506 {
507 minSegments = 3;
508 }
509
510 switch ( method )
511 {
513 return calculateSegmentsStandard( radius, parameter, minSegments );
515 return calculateSegmentsAdaptive( radius, parameter, minSegments );
517 return calculateSegmentsByAreaError( radius, parameter, minSegments );
519 return calculateSegmentsByConstant( radius, parameter, minSegments );
520 default:
521 return calculateSegmentsStandard( radius, parameter, minSegments );
522 }
523}
SegmentCalculationMethod
brief Method used to calculate the number of segments for circle approximation
Definition qgis.h:6398
@ AreaError
Calculation based on area error.
Definition qgis.h:6401
@ Adaptive
Adaptive calculation based on radius size.
Definition qgis.h:6400
@ ConstantDensity
Simple calculation with constant segment density.
Definition qgis.h:6402
@ Standard
Standard sagitta-based calculation.
Definition qgis.h:6399
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:46
static QgsCircle from2Points(const QgsPoint &pt1, const QgsPoint &pt2)
Constructs a circle by 2 points on the circle.
Definition qgscircle.cpp:41
int intersections(const QgsCircle &other, QgsPoint &intersection1, QgsPoint &intersection2, bool useZ=false) const
Calculates the intersections points between this circle and an other circle.
double radius() const
Returns the radius of the circle.
Definition qgscircle.h:301
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.
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.
void setSemiMinorAxis(double semiMinorAxis) override
Inherited method.
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.
void setSemiMajorAxis(double semiMajorAxis) override
Inherited method.
QString toString(int pointPrecision=17, int radiusPrecision=17, int azimuthPrecision=2) const override
returns a string representation of the ellipse.
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).
QgsRectangle boundingBox() const override
Returns the minimal bounding box for the ellipse.
bool contains(const QgsPoint &point, double epsilon=1E-8) const
Returns true if the circle contains the point.
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...
static QgsCircle fromExtent(const QgsPoint &pt1, const QgsPoint &pt2)
Constructs a circle by an extent (aka bounding box / QgsRectangle).
double area() const override
The area of the ellipse.
static QgsCircle fromCenterDiameter(const QgsPoint &center, double diameter, double azimuth=0)
Constructs a circle by a center point and a diameter.
static int calculateSegments(double radius, double parameter, int minSegments, Qgis::SegmentCalculationMethod method)
Calculates the number of segments needed to approximate a circle.
static QgsCircle fromCenterPoint(const QgsPoint &center, const QgsPoint &pt1)
Constructs a circle by a center point and another point.
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.
QgsCircularString * toCircularString(bool oriented=false) const
Returns a circular string from the circle.
double perimeter() const override
The circumference of the ellipse using first approximation of Ramanujan.
bool tangentToPoint(const QgsPointXY &p, QgsPointXY &pt1, QgsPointXY &pt2) const
Calculates the tangent points between this circle and the point p.
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:86
QVector< QgsPoint > northQuadrant() const
The four quadrants of the ellipse.
static QgsCircle minimalCircleFrom3Points(const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double epsilon=1E-8)
Constructs the smallest circle from 3 points.
Circular string geometry type.
QgsPoint mCenter
Definition qgsellipse.h:253
QgsPoint center() const
Returns the center point.
Definition qgsellipse.h:122
double semiMajorAxis() const
Returns the semi-major axis.
Definition qgsellipse.h:128
double mAzimuth
Definition qgsellipse.h:256
virtual QgsPointSequence points(unsigned int segments=36) const
Returns a list of points with segmentation from segments.
double mSemiMajorAxis
Definition qgsellipse.h:254
double azimuth() const
Returns the azimuth.
Definition qgsellipse.h:140
virtual QVector< QgsPoint > quadrant() const
The four quadrants of the ellipse.
QgsEllipse()=default
Constructor for QgsEllipse.
virtual bool isEmpty() const
An ellipse is empty if axes are equal to 0.
double mSemiMinorAxis
Definition qgsellipse.h:255
double semiMinorAxis() const
Returns the semi-minor axis.
Definition qgsellipse.h:134
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.
Represents a 2D point.
Definition qgspointxy.h:62
Point geometry type, with support for z-dimension and m-values.
Definition qgspoint.h:53
void setY(double y)
Sets the point's y-coordinate.
Definition qgspoint.h:370
bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value.
Definition qgspoint.cpp:582
void setX(double x)
Sets the point's x-coordinate.
Definition qgspoint.h:359
double z
Definition qgspoint.h:58
double x
Definition qgspoint.h:56
bool convertTo(Qgis::WkbType type) override
Converts the geometry to a specified type.
Definition qgspoint.cpp:651
bool isEmpty() const override
Returns true if the geometry is empty.
Definition qgspoint.cpp:760
double distance(double x, double y) const
Returns the Cartesian 2D distance between this point and a specified x, y coordinate.
Definition qgspoint.h:449
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:728
double y
Definition qgspoint.h:57
A rectangle specified with double values.
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.
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Definition qgis.h:6852
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
Definition qgis.h:6935
QVector< QgsPoint > QgsPointSequence