QGIS API Documentation 4.1.0-Master (60fea48833c)
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
38
40{
42 const double azimuth = QgsGeometryUtilsBase::lineAngle( pt1.x(), pt1.y(), pt2.x(), pt2.y() ) * 180.0 / M_PI;
43 const double radius = pt1.distance( pt2 ) / 2.0;
44
46
47 return QgsCircle( center, radius, azimuth );
48}
49
50static bool isPerpendicular( const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double epsilon )
51{
52 // check the given point are perpendicular to x or y axis
53
54 const double yDelta_a = pt2.y() - pt1.y();
55 const double xDelta_a = pt2.x() - pt1.x();
56 const double yDelta_b = pt3.y() - pt2.y();
57 const double xDelta_b = pt3.x() - pt2.x();
58
59 if ( ( std::fabs( xDelta_a ) <= epsilon ) && ( std::fabs( yDelta_b ) <= epsilon ) )
60 {
61 return false;
62 }
63
64 if ( std::fabs( yDelta_a ) <= epsilon )
65 {
66 return true;
67 }
68 else if ( std::fabs( yDelta_b ) <= epsilon )
69 {
70 return true;
71 }
72 else if ( std::fabs( xDelta_a ) <= epsilon )
73 {
74 return true;
75 }
76 else if ( std::fabs( xDelta_b ) <= epsilon )
77 {
78 return true;
79 }
80
81 return false;
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( ( aSlope * bSlope * ( p1.y() - p3.y() ) + bSlope * ( p1.x() + p2.x() ) - aSlope * ( p2.x() + p3.x() ) ) / ( 2.0 * ( bSlope - aSlope ) ) );
162 center.setY( -1.0 * ( center.x() - ( p1.x() + p2.x() ) / 2.0 ) / aSlope + ( p1.y() + p2.y() ) / 2.0 );
163
164 radius = center.distance( p1 );
165
166 return QgsCircle( center, radius );
167}
168
170{
171 return QgsCircle( center, diameter / 2.0, azimuth );
172}
173
174QgsCircle QgsCircle::fromCenterPoint( const QgsPoint &center, const QgsPoint &pt1 ) // cppcheck-suppress duplInheritedMember
175{
176 const double azimuth = QgsGeometryUtilsBase::lineAngle( center.x(), center.y(), pt1.x(), pt1.y() ) * 180.0 / M_PI;
177
178 QgsPoint centerPt( center );
180
181 return QgsCircle( centerPt, centerPt.distance( pt1 ), azimuth );
182}
183
184static QVector<QgsCircle> from2ParallelsLine(
185 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
186)
187{
188 const double radius = QgsGeometryUtils::perpendicularSegment( pt1_par2, pt1_par1, pt2_par1 ).length() / 2.0;
189
190 bool isInter;
191 const QgsPoint ptInter;
192 QVector<QgsCircle> circles;
193
194 QgsPoint ptInter_par1line1, ptInter_par2line1;
195 double angle1, angle2;
196 double x, y;
197 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 );
198 ptInter_par1line1.setX( x );
199 ptInter_par1line1.setY( y );
200
201 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 );
202 ptInter_par2line1.setX( x );
203 ptInter_par2line1.setY( y );
204
205 QgsPoint center;
206 QgsGeometryUtils::segmentIntersection( ptInter_par1line1, ptInter_par1line1.project( 1.0, angle1 ), ptInter_par2line1, ptInter_par2line1.project( 1.0, angle2 ), center, isInter, epsilon, true );
207 if ( isInter )
208 {
209 if ( !pos.isEmpty() )
210 {
211 if ( QgsGeometryUtils::leftOfLine( center, pt1_line1, pt2_line1 ) == QgsGeometryUtils::leftOfLine( pos, pt1_line1, pt2_line1 ) )
212 {
213 circles.append( QgsCircle( center, radius ) );
214 }
215 }
216 else
217 {
218 circles.append( QgsCircle( center, radius ) );
219 }
220 }
221
222 QgsGeometryUtils::segmentIntersection( ptInter_par1line1, ptInter_par1line1.project( 1.0, angle1 ), ptInter_par2line1, ptInter_par2line1.project( 1.0, angle2 + 90.0 ), center, isInter, epsilon, true );
223 if ( isInter )
224 {
225 if ( !pos.isEmpty() )
226 {
227 if ( QgsGeometryUtils::leftOfLine( center, pt1_line1, pt2_line1 ) == QgsGeometryUtils::leftOfLine( pos, pt1_line1, pt2_line1 ) )
228 {
229 circles.append( QgsCircle( center, radius ) );
230 }
231 }
232 else
233 {
234 circles.append( QgsCircle( center, radius ) );
235 }
236 }
237
238 QgsGeometryUtils::segmentIntersection( ptInter_par1line1, ptInter_par1line1.project( 1.0, angle1 + 90.0 ), ptInter_par2line1, ptInter_par2line1.project( 1.0, angle2 ), center, isInter, epsilon, true );
239 if ( isInter && !circles.contains( QgsCircle( center, radius ) ) )
240 {
241 if ( !pos.isEmpty() )
242 {
243 if ( QgsGeometryUtils::leftOfLine( center, pt1_line1, pt2_line1 ) == QgsGeometryUtils::leftOfLine( pos, pt1_line1, pt2_line1 ) )
244 {
245 circles.append( QgsCircle( center, radius ) );
246 }
247 }
248 else
249 {
250 circles.append( QgsCircle( center, radius ) );
251 }
252 }
253 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 );
254 if ( isInter && !circles.contains( QgsCircle( center, radius ) ) )
255 {
256 if ( !pos.isEmpty() )
257 {
258 if ( QgsGeometryUtils::leftOfLine( center, pt1_line1, pt2_line1 ) == QgsGeometryUtils::leftOfLine( pos, pt1_line1, pt2_line1 ) )
259 {
260 circles.append( QgsCircle( center, radius ) );
261 }
262 }
263 else
264 {
265 circles.append( QgsCircle( center, radius ) );
266 }
267 }
268
269 return circles;
270}
271
273 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
274)
275{
276 QgsPoint p1, p2, p3;
277 bool isIntersect_tg1tg2 = false;
278 bool isIntersect_tg1tg3 = false;
279 bool isIntersect_tg2tg3 = false;
280 QgsGeometryUtils::segmentIntersection( pt1_tg1, pt2_tg1, pt1_tg2, pt2_tg2, p1, isIntersect_tg1tg2, epsilon );
281 QgsGeometryUtils::segmentIntersection( pt1_tg1, pt2_tg1, pt1_tg3, pt2_tg3, p2, isIntersect_tg1tg3, epsilon );
282 QgsGeometryUtils::segmentIntersection( pt1_tg2, pt2_tg2, pt1_tg3, pt2_tg3, p3, isIntersect_tg2tg3, epsilon );
283
284 QVector<QgsCircle> circles;
285 if ( !isIntersect_tg1tg2 && !isIntersect_tg2tg3 ) // three lines are parallels
286 return circles;
287
288 if ( !isIntersect_tg1tg2 )
289 return from2ParallelsLine( pt1_tg1, pt2_tg1, pt1_tg2, pt2_tg2, pt1_tg3, pt2_tg3, pos, epsilon );
290 else if ( !isIntersect_tg1tg3 )
291 return from2ParallelsLine( pt1_tg1, pt2_tg1, pt1_tg3, pt2_tg3, pt1_tg2, pt2_tg2, pos, epsilon );
292 else if ( !isIntersect_tg2tg3 )
293 return from2ParallelsLine( pt1_tg2, pt2_tg2, pt1_tg3, pt2_tg3, pt1_tg1, pt1_tg1, pos, epsilon );
294
295 if ( p1.is3D() )
296 {
298 }
299
300 if ( p2.is3D() )
301 {
303 }
304
305 if ( p3.is3D() )
306 {
308 }
309
310 circles.append( QgsTriangle( p1, p2, p3 ).inscribedCircle() );
311 return circles;
312}
313
315 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
316)
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.arg( mCenter.asWkt( pointPrecision ), 0, 's' )
464 .arg( qgsDoubleToString( mSemiMajorAxis, radiusPrecision ), 0, 'f' )
465 .arg( qgsDoubleToString( mAzimuth, azimuthPrecision ), 0, 'f' );
466
467 return rep;
468}
469
470QDomElement QgsCircle::asGml2( QDomDocument &doc, int precision, const QString &ns, const QgsAbstractGeometry::AxisOrder axisOrder ) const
471{
472 // Gml2 does not support curve. It will be converted to a linestring via CircularString
473 std::unique_ptr< QgsCircularString > circularString( toCircularString() );
474 const QDomElement gml = circularString->asGml2( doc, precision, ns, axisOrder );
475 return gml;
476}
477
478QDomElement QgsCircle::asGml3( QDomDocument &doc, int precision, const QString &ns, const QgsAbstractGeometry::AxisOrder axisOrder ) const
479{
481 pts << northQuadrant().at( 0 ) << northQuadrant().at( 1 ) << northQuadrant().at( 2 );
482
483 QDomElement elemCircle = doc.createElementNS( ns, u"Circle"_s );
484
485 if ( isEmpty() )
486 return elemCircle;
487
488 elemCircle.appendChild( QgsGeometryUtils::pointsToGML3( pts, doc, precision, ns, mCenter.is3D(), axisOrder ) );
489 return elemCircle;
490}
491
492int QgsCircle::calculateSegments( double radius, double parameter, int minSegments, Qgis::SegmentCalculationMethod method )
493{
494 if ( radius <= 0.0 )
495 {
496 return minSegments;
497 }
498
499 if ( parameter <= 0.0 )
500 {
501 parameter = 0.01;
502 }
503
504 if ( minSegments < 3 )
505 {
506 minSegments = 3;
507 }
508
509 switch ( method )
510 {
512 return calculateSegmentsStandard( radius, parameter, minSegments );
514 return calculateSegmentsAdaptive( radius, parameter, minSegments );
516 return calculateSegmentsByAreaError( radius, parameter, minSegments );
518 return calculateSegmentsByConstant( radius, parameter, minSegments );
519 default:
520 return calculateSegmentsStandard( radius, parameter, minSegments );
521 }
522}
SegmentCalculationMethod
brief Method used to calculate the number of segments for circle approximation
Definition qgis.h:6455
@ AreaError
Calculation based on area error.
Definition qgis.h:6458
@ Adaptive
Adaptive calculation based on radius size.
Definition qgis.h:6457
@ ConstantDensity
Simple calculation with constant segment density.
Definition qgis.h:6459
@ Standard
Standard sagitta-based calculation.
Definition qgis.h:6456
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:39
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:303
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:84
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:255
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:258
virtual QgsPointSequence points(unsigned int segments=36) const
Returns a list of points with segmentation from segments.
double mSemiMajorAxis
Definition qgsellipse.h:256
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:257
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:387
bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value.
Definition qgspoint.cpp:588
void setX(double x)
Sets the point's x-coordinate.
Definition qgspoint.h:376
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:657
bool isEmpty() const override
Returns true if the geometry is empty.
Definition qgspoint.cpp:766
double distance(double x, double y) const
Returns the Cartesian 2D distance between this point and a specified x, y coordinate.
Definition qgspoint.h:466
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:734
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:6893
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
Definition qgis.h:6975
QVector< QgsPoint > QgsPointSequence