QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgstriangle.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgstriangle.cpp
3 -------------------
4 begin : January 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 "qgstriangle.h"
19#include "qgsgeometryutils.h"
20#include "qgslinestring.h"
21#include "qgswkbptr.h"
22
23#include <memory>
24
26{
28}
29
30QgsTriangle::QgsTriangle( const QgsPoint &p1, const QgsPoint &p2, const QgsPoint &p3 )
31{
33
34 const QVector< double > x { p1.x(), p2.x(), p3.x(), p1.x() };
35 const QVector< double > y { p1.y(), p2.y(), p3.y(), p1.y() };
36 QVector< double > z;
37 if ( p1.is3D() )
38 {
39 z = { p1.z(), p2.z(), p3.z(), p1.z() };
40 }
41 QVector< double > m;
42 if ( p1.isMeasure() )
43 {
44 m = {p1.m(), p2.m(), p3.m(), p1.m() };
45 }
46 setExteriorRing( new QgsLineString( x, y, z, m ) );
47}
48
49QgsTriangle::QgsTriangle( const QgsPointXY &p1, const QgsPointXY &p2, const QgsPointXY &p3 )
50{
52
53 const QVector< double > x { p1.x(), p2.x(), p3.x(), p1.x() };
54 const QVector< double > y {p1.y(), p2.y(), p3.y(), p1.y() };
55 QgsLineString *ext = new QgsLineString( x, y );
56 setExteriorRing( ext );
57}
58
59QgsTriangle::QgsTriangle( const QPointF p1, const QPointF p2, const QPointF p3 )
60{
62
63 const QVector< double > x{ p1.x(), p2.x(), p3.x(), p1.x() };
64 const QVector< double > y{ p1.y(), p2.y(), p3.y(), p1.y() };
65 QgsLineString *ext = new QgsLineString( x, y );
66 setExteriorRing( ext );
67}
68
70{
71 const QgsTriangle *otherTriangle = qgsgeometry_cast< const QgsTriangle * >( &other );
72 if ( !otherTriangle )
73 return false;
74
75 if ( isEmpty() && otherTriangle->isEmpty() )
76 {
77 return true;
78 }
79 else if ( isEmpty() || otherTriangle->isEmpty() )
80 {
81 return false;
82 }
83
84 return ( ( vertexAt( 0 ) == otherTriangle->vertexAt( 0 ) ) &&
85 ( vertexAt( 1 ) == otherTriangle->vertexAt( 1 ) ) &&
86 ( vertexAt( 2 ) == otherTriangle->vertexAt( 2 ) ) );
87}
88
90{
91 return !operator==( other );
92}
93
95{
96 return QStringLiteral( "Triangle" );
97}
98
100{
101 auto result = std::make_unique< QgsTriangle >();
102 result->mWkbType = mWkbType;
103 return result.release();
104}
105
107{
110}
111
113{
114 return new QgsTriangle( *this );
115}
116
118{
119 clear();
120 if ( !wkbPtr )
121 {
122 return false;
123 }
124
125 const Qgis::WkbType type = wkbPtr.readHeader();
127 {
128 return false;
129 }
130 mWkbType = type;
131
132 Qgis::WkbType ringType;
133 switch ( mWkbType )
134 {
137 break;
140 break;
143 break;
144 default:
145 ringType = Qgis::WkbType::LineString;
146 break;
147 }
148
149 int nRings;
150 wkbPtr >> nRings;
151 if ( nRings > 1 )
152 {
153 return false;
154 }
155
156 QgsLineString *line = new QgsLineString();
157 line->fromWkbPoints( ringType, wkbPtr );
158 mExteriorRing.reset( line );
159
160 return true;
161}
162
163bool QgsTriangle::fromWkt( const QString &wkt )
164{
165 clear();
166
167 const QPair<Qgis::WkbType, QString> parts = QgsGeometryUtils::wktReadBlock( wkt );
168
170 return false;
171
172 mWkbType = parts.first;
173
174 QString secondWithoutParentheses = parts.second;
175 secondWithoutParentheses = secondWithoutParentheses.simplified().remove( ' ' );
176 if ( ( parts.second.compare( QLatin1String( "EMPTY" ), Qt::CaseInsensitive ) == 0 ) ||
177 secondWithoutParentheses.isEmpty() )
178 return true;
179
180 const QString defaultChildWkbType = QStringLiteral( "LineString%1%2" ).arg( is3D() ? QStringLiteral( "Z" ) : QString(), isMeasure() ? QStringLiteral( "M" ) : QString() );
181
182 const QStringList blocks = QgsGeometryUtils::wktGetChildBlocks( parts.second, defaultChildWkbType );
183 for ( const QString &childWkt : blocks )
184 {
185 const QPair<Qgis::WkbType, QString> childParts = QgsGeometryUtils::wktReadBlock( childWkt );
186
187 const Qgis::WkbType flatCurveType = QgsWkbTypes::flatType( childParts.first );
188
189 if ( flatCurveType == Qgis::WkbType::LineString )
190 mInteriorRings.append( new QgsLineString() );
191 else
192 {
193 clear();
194 return false;
195 }
196 if ( !mInteriorRings.back()->fromWkt( childWkt ) )
197 {
198 clear();
199 return false;
200 }
201 }
202
203 mExteriorRing.reset( mInteriorRings.takeFirst() );
204 if ( ( mExteriorRing->numPoints() < 3 ) || ( mExteriorRing->numPoints() > 4 ) || ( mExteriorRing->numPoints() == 4 && mExteriorRing->startPoint() != mExteriorRing->endPoint() ) )
205 {
206 clear();
207 return false;
208 }
209
210 //scan through rings and check if dimensionality of rings is different to CurvePolygon.
211 //if so, update the type dimensionality of the CurvePolygon to match
212 bool hasZ = false;
213 bool hasM = false;
214 if ( mExteriorRing )
215 {
216 hasZ = hasZ || mExteriorRing->is3D();
217 hasM = hasM || mExteriorRing->isMeasure();
218 }
219 if ( hasZ )
220 addZValue( 0 );
221 if ( hasM )
222 addMValue( 0 );
223
224 return true;
225}
226
227QDomElement QgsTriangle::asGml3( QDomDocument &doc, int precision, const QString &ns, const AxisOrder axisOrder ) const
228{
229
230 QDomElement elemTriangle = doc.createElementNS( ns, QStringLiteral( "Triangle" ) );
231
232 if ( isEmpty() )
233 return elemTriangle;
234
235 QDomElement elemExterior = doc.createElementNS( ns, QStringLiteral( "exterior" ) );
236 QDomElement curveElem = exteriorRing()->asGml3( doc, precision, ns, axisOrder );
237 if ( curveElem.tagName() == QLatin1String( "LineString" ) )
238 {
239 curveElem.setTagName( QStringLiteral( "LinearRing" ) );
240 }
241 elemExterior.appendChild( curveElem );
242 elemTriangle.appendChild( elemExterior );
243
244 return elemTriangle;
245}
246
248{
249 return toPolygon();
250}
251
253{
254 std::unique_ptr<QgsCurvePolygon> curvePolygon( new QgsCurvePolygon() );
255 curvePolygon->setExteriorRing( mExteriorRing->clone() );
256
257 return curvePolygon.release();
258}
259
261{
262 delete ring;
263}
264
266{
267 Q_UNUSED( position )
268 return false;
269}
270
271bool QgsTriangle::insertVertex( QgsVertexId position, const QgsPoint &vertex )
272{
273 Q_UNUSED( position )
274 Q_UNUSED( vertex )
275 return false;
276}
277
279{
280 if ( isEmpty() )
281 return false;
282
283 if ( !mExteriorRing || vId.part != 0 || vId.ring != 0 || vId.vertex < 0 || vId.vertex > 4 )
284 {
285 return false;
286 }
287
288 if ( vId.vertex == 4 )
289 {
290 vId.vertex = 0;
291 }
292
293 const int n = mExteriorRing->numPoints();
294 const bool success = mExteriorRing->moveVertex( vId, newPos );
295 if ( success )
296 {
297 // If first or last vertex is moved, also move the last/first vertex
298 if ( vId.vertex == 0 )
299 mExteriorRing->moveVertex( QgsVertexId( vId.part, vId.ring, n - 1 ), newPos );
300 clearCache();
301 }
302 return success;
303}
304
306{
307 if ( !ring )
308 {
309 return;
310 }
311
312 if ( ring->hasCurvedSegments() )
313 {
314 //need to segmentize ring as polygon does not support curves
315 QgsCurve *line = ring->segmentize();
316 delete ring;
317 ring = line;
318 }
319
320 if ( ( ring->numPoints() > 4 ) || ( ring->numPoints() < 3 ) )
321 {
322 delete ring;
323 return;
324 }
325 else if ( ring->numPoints() == 4 )
326 {
327 if ( !ring->isClosed() )
328 {
329 delete ring;
330 return;
331 }
332 }
333 else if ( ring->numPoints() == 3 )
334 {
335 if ( ring->isClosed() )
336 {
337 delete ring;
338 return;
339 }
340 QgsLineString *lineString = static_cast< QgsLineString *>( ring );
341 if ( !lineString->isClosed() )
342 {
343 lineString->close();
344 }
345 ring = lineString;
346 }
347
348 mExteriorRing.reset( ring );
349
350 //set proper wkb type
352
353 clearCache();
354}
355
357{
358 if ( !mExteriorRing )
359 return nullptr;
360
361 return mExteriorRing->clone();
362}
363
364QgsPoint QgsTriangle::vertexAt( int atVertex ) const
365{
366 if ( isEmpty() )
367 return QgsPoint();
368
369 const QgsVertexId id( 0, 0, atVertex );
370 return mExteriorRing->vertexAt( id );
371}
372
373QVector<double> QgsTriangle::lengths() const
374{
375 QVector<double> lengths;
376 if ( isEmpty() )
377 return lengths;
378
379 lengths.append( vertexAt( 0 ).distance( vertexAt( 1 ) ) ); // c = |AB|
380 lengths.append( vertexAt( 1 ).distance( vertexAt( 2 ) ) ); // a = |BC|
381 lengths.append( vertexAt( 0 ).distance( vertexAt( 2 ) ) ); // b = |AC|
382
383 return lengths;
384}
385
386QVector<double> QgsTriangle::angles() const
387{
388 QVector<double> angles;
389 if ( isEmpty() )
390 return angles;
391
392 QVector<double> l = lengths();
393
394 const double a = l[1];
395 const double b = l[2];
396 const double c = l[0];
397
398 const double a2 = a * a;
399 const double b2 = b * b;
400 const double c2 = c * c;
401
402 const double alpha = acos( ( b2 + c2 - a2 ) / ( 2 * b * c ) );
403 const double beta = acos( ( a2 + c2 - b2 ) / ( 2 * a * c ) );
404 const double gamma = M_PI - alpha - beta; // acos((a2 + b2 - c2)/(2*a*b)); but ensure that alpha+beta+gamma = 180.0
405
406 angles.append( alpha );
407 angles.append( beta );
408 angles.append( gamma );
409
410 return angles;
411}
412
414{
415 if ( isEmpty() )
416 return true;
417
418 const QgsPoint p1( vertexAt( 0 ) );
419 const QgsPoint p2( vertexAt( 1 ) );
420 const QgsPoint p3( vertexAt( 2 ) );
421 return ( ( ( p1 == p2 ) || ( p1 == p3 ) || ( p2 == p3 ) ) || QgsGeometryUtilsBase::leftOfLine( p1.x(), p1.y(), p2.x(), p2.y(), p3.x(), p3.y() ) == 0 );
422}
423
424bool QgsTriangle::isIsocele( double lengthTolerance ) const
425{
426 if ( isEmpty() )
427 return false;
428 const QVector<double> sides = lengths();
429 const bool ab_bc = qgsDoubleNear( sides.at( 0 ), sides.at( 1 ), lengthTolerance );
430 const bool bc_ca = qgsDoubleNear( sides.at( 1 ), sides.at( 2 ), lengthTolerance );
431 const bool ca_ab = qgsDoubleNear( sides.at( 2 ), sides.at( 0 ), lengthTolerance );
432
433 return ( ab_bc || bc_ca || ca_ab );
434}
435
436bool QgsTriangle::isEquilateral( double lengthTolerance ) const
437{
438 if ( isEmpty() )
439 return false;
440 const QVector<double> sides = lengths();
441 const bool ab_bc = qgsDoubleNear( sides.at( 0 ), sides.at( 1 ), lengthTolerance );
442 const bool bc_ca = qgsDoubleNear( sides.at( 1 ), sides.at( 2 ), lengthTolerance );
443 const bool ca_ab = qgsDoubleNear( sides.at( 2 ), sides.at( 0 ), lengthTolerance );
444
445 return ( ab_bc && bc_ca && ca_ab );
446}
447
448bool QgsTriangle::isRight( double angleTolerance ) const
449{
450 if ( isEmpty() )
451 return false;
452 QVector<double> a = angles();
453 QVector<double>::iterator ita = a.begin();
454 while ( ita != a.end() )
455 {
456 if ( qgsDoubleNear( *ita, M_PI_2, angleTolerance ) )
457 return true;
458 ++ita;
459 }
460 return false;
461}
462
463bool QgsTriangle::isScalene( double lengthTolerance ) const
464{
465 if ( isEmpty() )
466 return false;
467 return !isIsocele( lengthTolerance );
468}
469
470QVector<QgsLineString> QgsTriangle::altitudes() const
471{
472 QVector<QgsLineString> alt;
473 if ( isEmpty() )
474 return alt;
475
476 alt.append( QgsGeometryUtils::perpendicularSegment( vertexAt( 0 ), vertexAt( 2 ), vertexAt( 1 ) ) );
477 alt.append( QgsGeometryUtils::perpendicularSegment( vertexAt( 1 ), vertexAt( 0 ), vertexAt( 2 ) ) );
478 alt.append( QgsGeometryUtils::perpendicularSegment( vertexAt( 2 ), vertexAt( 0 ), vertexAt( 1 ) ) );
479
480 return alt;
481}
482
483QVector<QgsLineString> QgsTriangle::medians() const
484{
485 QVector<QgsLineString> med;
486 if ( isEmpty() )
487 return med;
488
489 QgsLineString med1;
490 QgsLineString med2;
491 QgsLineString med3;
495 med.append( med1 );
496 med.append( med2 );
497 med.append( med3 );
498
499 return med;
500}
501
502QVector<QgsLineString> QgsTriangle::bisectors( double lengthTolerance ) const
503{
504 QVector<QgsLineString> bis;
505 if ( isEmpty() )
506 return bis;
507
508 QgsLineString bis1;
509 QgsLineString bis2;
510 QgsLineString bis3;
511 const QgsPoint incenter = inscribedCenter();
512 QgsPoint out;
513 bool intersection = false;
514
515 QgsGeometryUtils::segmentIntersection( vertexAt( 0 ), incenter, vertexAt( 1 ), vertexAt( 2 ), out, intersection, lengthTolerance );
516 bis1.setPoints( QgsPointSequence() << vertexAt( 0 ) << out );
517
518 QgsGeometryUtils::segmentIntersection( vertexAt( 1 ), incenter, vertexAt( 0 ), vertexAt( 2 ), out, intersection, lengthTolerance );
519 bis2.setPoints( QgsPointSequence() << vertexAt( 1 ) << out );
520
521 QgsGeometryUtils::segmentIntersection( vertexAt( 2 ), incenter, vertexAt( 0 ), vertexAt( 1 ), out, intersection, lengthTolerance );
522 bis3.setPoints( QgsPointSequence() << vertexAt( 2 ) << out );
523
524 bis.append( bis1 );
525 bis.append( bis2 );
526 bis.append( bis3 );
527
528 return bis;
529}
530
532{
533 if ( isEmpty() )
534 return QgsTriangle();
535 QgsPoint p1, p2, p3;
539 return QgsTriangle( p1, p2, p3 );
540}
541
542QgsPoint QgsTriangle::orthocenter( double lengthTolerance ) const
543{
544 if ( isEmpty() )
545 return QgsPoint();
546 const QVector<QgsLineString> alt = altitudes();
547 QgsPoint ortho;
548 bool intersection;
549 QgsGeometryUtils::segmentIntersection( alt.at( 0 ).pointN( 0 ), alt.at( 0 ).pointN( 1 ), alt.at( 1 ).pointN( 0 ), alt.at( 1 ).pointN( 1 ), ortho, intersection, lengthTolerance );
550
551 return ortho;
552}
553
555{
556 if ( isEmpty() )
557 return QgsPoint();
558 double r, x, y;
560 return QgsPoint( x, y );
561}
562
564{
565 if ( isEmpty() )
566 return 0.0;
567 double r, x, y;
569 return r;
570}
571
573{
574 if ( isEmpty() )
575 return QgsCircle();
577}
578
580{
581 if ( isEmpty() )
582 return QgsPoint();
583
584 const QVector<double> l = lengths();
585 const double x = ( l.at( 0 ) * vertexAt( 2 ).x() +
586 l.at( 1 ) * vertexAt( 0 ).x() +
587 l.at( 2 ) * vertexAt( 1 ).x() ) / perimeter();
588 const double y = ( l.at( 0 ) * vertexAt( 2 ).y() +
589 l.at( 1 ) * vertexAt( 0 ).y() +
590 l.at( 2 ) * vertexAt( 1 ).y() ) / perimeter();
591
592 QgsPoint center( x, y );
593
594 QgsPointSequence points;
595 points << vertexAt( 0 ) << vertexAt( 1 ) << vertexAt( 2 );
597
598 return center;
599}
600
602{
603 if ( isEmpty() )
604 return 0.0;
605 return ( 2.0 * area() / perimeter() );
606}
607
609{
610 if ( isEmpty() )
611 return QgsCircle();
613}
@ Polygon
Polygons.
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition: qgis.h:182
@ LineStringM
LineStringM.
@ LineString
LineString.
@ LineStringZM
LineStringZM.
@ TriangleZ
TriangleZ.
@ Triangle
Triangle.
@ TriangleZM
TriangleZM.
@ TriangleM
TriangleM.
@ LineStringZ
LineStringZ.
Abstract base class for all geometries.
bool isMeasure() const
Returns true if the geometry contains m values.
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
AxisOrder
Axis order for GML generation.
void setZMTypeFromSubGeometry(const QgsAbstractGeometry *subggeom, Qgis::WkbType baseGeomType)
Updates the geometry type based on whether sub geometries contain z or m values.
virtual QDomElement asGml3(QDomDocument &doc, int precision=17, const QString &ns="gml", AxisOrder axisOrder=QgsAbstractGeometry::AxisOrder::XY) const =0
Returns a GML3 representation of the geometry.
virtual bool hasCurvedSegments() const
Returns true if the geometry contains curved segments.
QgsGeometryConstPartIterator parts() const
Returns Java-style iterator for traversal of parts of the geometry.
Circle geometry type.
Definition: qgscircle.h:43
A const WKB pointer.
Definition: qgswkbptr.h:138
Qgis::WkbType readHeader() const
readHeader
Definition: qgswkbptr.cpp:55
Curve polygon geometry type.
bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value.
const QgsCurve * exteriorRing() const
Returns the curve polygon's exterior ring.
bool isEmpty() const override
Returns true if the geometry is empty.
virtual QgsPolygon * toPolygon(double tolerance=M_PI_2/90, SegmentationToleranceType toleranceType=MaximumAngle) const
Returns a new polygon geometry corresponding to a segmentized approximation of the curve.
QVector< QgsCurve * > mInteriorRings
double area() const override
Returns the planar, 2-dimensional area of the geometry.
double perimeter() const override
Returns the planar, 2-dimensional perimeter of the geometry.
bool addMValue(double mValue=0) override
Adds a measure to the geometry, initialized to a preset value.
std::unique_ptr< QgsCurve > mExteriorRing
Abstract base class for curved geometry type.
Definition: qgscurve.h:35
virtual int numPoints() const =0
Returns the number of points in the curve.
QgsCurve * segmentize(double tolerance=M_PI_2/90, SegmentationToleranceType toleranceType=MaximumAngle) const override
Returns a geometry without curves.
Definition: qgscurve.cpp:175
virtual bool isClosed() const
Returns true if the curve is closed.
Definition: qgscurve.cpp:53
static int leftOfLine(const double x, const double y, const double x1, const double y1, const double x2, const double y2)
Returns a value < 0 if the point (x, y) is left of the line from (x1, y1) -> (x2, y2).
static QStringList wktGetChildBlocks(const QString &wkt, const QString &defaultType=QString())
Parses a WKT string and returns of list of blocks contained in the WKT.
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 QPair< Qgis::WkbType, QString > wktReadBlock(const QString &wkt)
Parses a WKT block of the format "TYPE( contents )" and returns a pair of geometry type to contents (...
static void circleCenterRadius(const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double &radius, double &centerX, double &centerY)
Returns radius and center of the circle through pt1, pt2, pt3.
static QgsPoint midpoint(const QgsPoint &pt1, const QgsPoint &pt2)
Returns a middle point between points pt1 and pt2.
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.
Line string geometry type, with support for z-dimension and m-values.
Definition: qgslinestring.h:45
bool isClosed() const override
Returns true if the curve is closed.
void setPoints(size_t size, const double *x, const double *y, const double *z=nullptr, const double *m=nullptr)
Resets the line string to match the specified point data.
void close()
Closes the line string by appending the first point to the end of the line, if it is not already clos...
A class to represent a 2D point.
Definition: qgspointxy.h:60
double y
Definition: qgspointxy.h:64
Q_GADGET double x
Definition: qgspointxy.h:63
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:49
Q_GADGET double x
Definition: qgspoint.h:52
double z
Definition: qgspoint.h:54
double m
Definition: qgspoint.h:55
double y
Definition: qgspoint.h:53
Polygon geometry type.
Definition: qgspolygon.h:33
void clear() override
Clears the geometry, ie reset it to a null geometry.
Definition: qgspolygon.cpp:59
friend class QgsCurvePolygon
Definition: qgspolygon.h:116
void clearCache() const override
Clears any cached parameters associated with the geometry, e.g., bounding boxes.
Definition: qgssurface.cpp:43
Triangle geometry type.
Definition: qgstriangle.h:33
bool fromWkt(const QString &wkt) override
Sets the geometry from a WKT string.
QgsPolygon * surfaceToPolygon() const override
Gets a polygon representation of this surface.
void clear() override
Clears the geometry, ie reset it to a null geometry.
QVector< double > angles() const
Returns the three angles of the triangle.
void setExteriorRing(QgsCurve *ring) override
Sets the exterior ring of the polygon.
QVector< QgsLineString > altitudes() const
An altitude is a segment (defined by a QgsLineString) from a vertex to the opposite side (or,...
QgsCurve * boundary() const override
Returns the closure of the combinatorial boundary of the geometry (ie the topological boundary of the...
QgsCircle inscribedCircle() const
Inscribed circle of the triangle.
QVector< double > lengths() const
Returns the three lengths of the triangle.
QgsTriangle * createEmptyWithSameType() const override
Creates a new geometry with the same class and same WKB type as the original and transfers ownership.
Definition: qgstriangle.cpp:99
bool deleteVertex(QgsVertexId position) override
Inherited method not used. You cannot delete or insert a vertex directly. Returns always false.
QgsPoint circumscribedCenter() const
Center of the circumscribed circle of the triangle.
QgsTriangle * clone() const override
Clones the geometry by performing a deep copy.
QgsPoint orthocenter(double lengthTolerance=0.0001) const
An orthocenter is the point of intersection of the altitudes of a triangle.
QgsTriangle medial() const
Medial (or midpoint) triangle of a triangle ABC is the triangle with vertices at the midpoints of the...
bool moveVertex(QgsVertexId vId, const QgsPoint &newPos) override
Moves a vertex within the geometry.
QgsCurvePolygon * toCurveType() const override
Returns the geometry converted to the more generic curve type QgsCurvePolygon.
bool isEquilateral(double lengthTolerance=0.0001) const
Is the triangle equilateral (three sides with the same length)?
void addInteriorRing(QgsCurve *ring) override
Inherited method not used. You cannot add an interior ring into a triangle.
bool operator!=(const QgsAbstractGeometry &other) const override
Definition: qgstriangle.cpp:89
QgsPoint inscribedCenter() const
Center of the inscribed circle of the triangle.
bool operator==(const QgsAbstractGeometry &other) const override
Definition: qgstriangle.cpp:69
QDomElement asGml3(QDomDocument &doc, int precision=17, const QString &ns="gml", QgsAbstractGeometry::AxisOrder axisOrder=QgsAbstractGeometry::AxisOrder::XY) const override
Returns a GML3 representation of the geometry.
QgsTriangle()
Constructor for an empty triangle geometry.
Definition: qgstriangle.cpp:25
bool isIsocele(double lengthTolerance=0.0001) const
Is the triangle isocele (two sides with the same length)?
bool insertVertex(QgsVertexId position, const QgsPoint &vertex) override
Inherited method not used. You cannot delete or insert a vertex directly. Returns always false.
QString geometryType() const override
Returns a unique string representing the geometry type.
Definition: qgstriangle.cpp:94
QgsPoint vertexAt(int atVertex) const
Returns coordinates of a vertex.
bool isDegenerate() const
Convenient method checking if the geometry is degenerate (have duplicate or colinear point(s)).
bool isScalene(double lengthTolerance=0.0001) const
Is the triangle scalene (all sides have different lengths)?
double circumscribedRadius() const
Radius of the circumscribed circle of the triangle.
QVector< QgsLineString > bisectors(double lengthTolerance=0.0001) const
The segment (defined by a QgsLineString) returned bisect the angle of a vertex to the opposite side.
bool isRight(double angleTolerance=0.0001) const
Is the triangle right-angled?
QgsCircle circumscribedCircle() const
Circumscribed circle of the triangle.
double inscribedRadius() const
Radius of the inscribed circle of the triangle.
QVector< QgsLineString > medians() const
A median is a segment (defined by a QgsLineString) from a vertex to the midpoint of the opposite side...
bool fromWkb(QgsConstWkbPtr &wkbPtr) override
Sets the geometry from a WKB string.
static Qgis::GeometryType geometryType(Qgis::WkbType type)
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
Definition: qgswkbtypes.h:862
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
Definition: qgswkbtypes.h:628
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
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
Utility class for identifying a unique vertex within a geometry.
Definition: qgsvertexid.h:30
int vertex
Vertex number.
Definition: qgsvertexid.h:94
int part
Part number.
Definition: qgsvertexid.h:88
int ring
Ring number.
Definition: qgsvertexid.h:91