QGIS API Documentation 3.99.0-Master (26c88405ac0)
Loading...
Searching...
No Matches
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
20#include <memory>
21
22#include "qgsgeometryutils.h"
23#include "qgslinestring.h"
24#include "qgswkbptr.h"
25
30
31QgsTriangle::QgsTriangle( const QgsPoint &p1, const QgsPoint &p2, const QgsPoint &p3 )
32{
34
35 const QVector< double > x { p1.x(), p2.x(), p3.x(), p1.x() };
36 const QVector< double > y { p1.y(), p2.y(), p3.y(), p1.y() };
37 QVector< double > z;
38 if ( p1.is3D() )
39 {
40 z = { p1.z(), p2.z(), p3.z(), p1.z() };
41 }
42 QVector< double > m;
43 if ( p1.isMeasure() )
44 {
45 m = {p1.m(), p2.m(), p3.m(), p1.m() };
46 }
47 setExteriorRing( new QgsLineString( x, y, z, m ) );
48}
49
50QgsTriangle::QgsTriangle( const QgsPointXY &p1, const QgsPointXY &p2, const QgsPointXY &p3 )
51{
53
54 const QVector< double > x { p1.x(), p2.x(), p3.x(), p1.x() };
55 const QVector< double > y {p1.y(), p2.y(), p3.y(), p1.y() };
56 QgsLineString *ext = new QgsLineString( x, y );
57 setExteriorRing( ext );
58}
59
60QgsTriangle::QgsTriangle( const QPointF p1, const QPointF p2, const QPointF p3 )
61{
63
64 const QVector< double > x{ p1.x(), p2.x(), p3.x(), p1.x() };
65 const QVector< double > y{ p1.y(), p2.y(), p3.y(), p1.y() };
66 QgsLineString *ext = new QgsLineString( x, y );
67 setExteriorRing( ext );
68}
69
71{
72 const QgsTriangle *otherTriangle = qgsgeometry_cast< const QgsTriangle * >( &other );
73 if ( !otherTriangle )
74 return false;
75
76 if ( isEmpty() && otherTriangle->isEmpty() )
77 {
78 return true;
79 }
80 else if ( isEmpty() || otherTriangle->isEmpty() )
81 {
82 return false;
83 }
84
85 return ( ( vertexAt( 0 ) == otherTriangle->vertexAt( 0 ) ) &&
86 ( vertexAt( 1 ) == otherTriangle->vertexAt( 1 ) ) &&
87 ( vertexAt( 2 ) == otherTriangle->vertexAt( 2 ) ) );
88}
89
91{
92 return !operator==( other );
93}
94
96{
97 return QStringLiteral( "Triangle" );
98}
99
101{
102 auto result = std::make_unique< QgsTriangle >();
103 result->mWkbType = mWkbType;
104 return result.release();
105}
106
112
114{
115 return new QgsTriangle( *this );
116}
117
119{
120 clear();
121 if ( !wkbPtr )
122 {
123 return false;
124 }
125
126 const Qgis::WkbType type = wkbPtr.readHeader();
128 {
129 return false;
130 }
131 mWkbType = type;
132
133 Qgis::WkbType ringType;
134 switch ( mWkbType )
135 {
138 break;
141 break;
144 break;
145 default:
146 ringType = Qgis::WkbType::LineString;
147 break;
148 }
149
150 int nRings;
151 wkbPtr >> nRings;
152 if ( nRings > 1 )
153 {
154 return false;
155 }
156
157 QgsLineString *line = new QgsLineString();
158 line->fromWkbPoints( ringType, wkbPtr );
159 mExteriorRing.reset( line );
160
161 return true;
162}
163
164bool QgsTriangle::fromWkt( const QString &wkt )
165{
166 clear();
167
168 const QPair<Qgis::WkbType, QString> parts = QgsGeometryUtils::wktReadBlock( wkt );
169
171 return false;
172
173 mWkbType = parts.first;
174
175 QString secondWithoutParentheses = parts.second;
176 secondWithoutParentheses = secondWithoutParentheses.simplified().remove( ' ' );
177 if ( ( parts.second.compare( QLatin1String( "EMPTY" ), Qt::CaseInsensitive ) == 0 ) ||
178 secondWithoutParentheses.isEmpty() )
179 return true;
180
181 const QString defaultChildWkbType = QStringLiteral( "LineString%1%2" ).arg( is3D() ? QStringLiteral( "Z" ) : QString(), isMeasure() ? QStringLiteral( "M" ) : QString() );
182
183 const QStringList blocks = QgsGeometryUtils::wktGetChildBlocks( parts.second, defaultChildWkbType );
184 for ( const QString &childWkt : blocks )
185 {
186 const QPair<Qgis::WkbType, QString> childParts = QgsGeometryUtils::wktReadBlock( childWkt );
187
188 const Qgis::WkbType flatCurveType = QgsWkbTypes::flatType( childParts.first );
189
190 if ( flatCurveType == Qgis::WkbType::LineString )
191 mInteriorRings.append( new QgsLineString() );
192 else
193 {
194 clear();
195 return false;
196 }
197 if ( !mInteriorRings.back()->fromWkt( childWkt ) )
198 {
199 clear();
200 return false;
201 }
202 }
203
204 mExteriorRing.reset( mInteriorRings.takeFirst() );
205 if ( !mExteriorRing || ( mExteriorRing->numPoints() < 3 ) || ( mExteriorRing->numPoints() > 4 ) || ( mExteriorRing->numPoints() == 4 && mExteriorRing->startPoint() != mExteriorRing->endPoint() ) )
206 {
207 clear();
208 return false;
209 }
210
211 bool hasZ = mExteriorRing->is3D();
212 bool hasM = mExteriorRing->isMeasure();
213 if ( hasZ )
214 addZValue( 0 );
215 if ( hasM )
216 addMValue( 0 );
217
218 return true;
219}
220
221QDomElement QgsTriangle::asGml3( QDomDocument &doc, int precision, const QString &ns, const AxisOrder axisOrder ) const
222{
223
224 QDomElement elemTriangle = doc.createElementNS( ns, QStringLiteral( "Triangle" ) );
225
226 if ( isEmpty() )
227 return elemTriangle;
228
229 QDomElement elemExterior = doc.createElementNS( ns, QStringLiteral( "exterior" ) );
230 QDomElement curveElem = exteriorRing()->asGml3( doc, precision, ns, axisOrder );
231 if ( curveElem.tagName() == QLatin1String( "LineString" ) )
232 {
233 curveElem.setTagName( QStringLiteral( "LinearRing" ) );
234 }
235 elemExterior.appendChild( curveElem );
236 elemTriangle.appendChild( elemExterior );
237
238 return elemTriangle;
239}
240
242{
243 return toPolygon();
244}
245
247{
248 auto curvePolygon = std::make_unique<QgsCurvePolygon>();
249 curvePolygon->setExteriorRing( mExteriorRing->clone() );
250
251 return curvePolygon.release();
252}
253
255{
256 delete ring;
257}
258
260{
261 Q_UNUSED( position )
262 return false;
263}
264
265bool QgsTriangle::insertVertex( QgsVertexId position, const QgsPoint &vertex )
266{
267 Q_UNUSED( position )
268 Q_UNUSED( vertex )
269 return false;
270}
271
273{
274 if ( isEmpty() )
275 return false;
276
277 if ( !mExteriorRing || vId.part != 0 || vId.ring != 0 || vId.vertex < 0 || vId.vertex > 4 )
278 {
279 return false;
280 }
281
282 if ( vId.vertex == 4 )
283 {
284 vId.vertex = 0;
285 }
286
287 const int n = mExteriorRing->numPoints();
288 const bool success = mExteriorRing->moveVertex( vId, newPos );
289 if ( success )
290 {
291 // If first or last vertex is moved, also move the last/first vertex
292 if ( vId.vertex == 0 )
293 mExteriorRing->moveVertex( QgsVertexId( vId.part, vId.ring, n - 1 ), newPos );
294 clearCache();
295 }
296 return success;
297}
298
300{
301 if ( !ring )
302 {
303 return;
304 }
305
306 if ( ring->hasCurvedSegments() )
307 {
308 //need to segmentize ring as polygon does not support curves
309 QgsCurve *line = ring->segmentize();
310 delete ring;
311 ring = line;
312 }
313
314 if ( ( ring->numPoints() > 4 ) || ( ring->numPoints() < 3 ) )
315 {
316 delete ring;
317 return;
318 }
319 else if ( ring->numPoints() == 4 )
320 {
321 if ( !ring->isClosed() )
322 {
323 delete ring;
324 return;
325 }
326 }
327 else if ( ring->numPoints() == 3 )
328 {
329 if ( ring->isClosed() )
330 {
331 delete ring;
332 return;
333 }
334 QgsLineString *lineString = static_cast< QgsLineString *>( ring );
335 if ( !lineString->isClosed() )
336 {
337 lineString->close();
338 }
339 ring = lineString;
340 }
341
342 mExteriorRing.reset( ring );
343
344 //set proper wkb type
346
347 clearCache();
348}
349
351{
352 if ( !mExteriorRing )
353 return nullptr;
354
355 return mExteriorRing->clone();
356}
357
359{
360 return QgsPolygon::vertexAt( id );
361}
362
363QgsPoint QgsTriangle::vertexAt( int atVertex ) const
364{
365 if ( isEmpty() )
366 return QgsPoint();
367
368 const QgsVertexId id( 0, 0, atVertex );
369 return mExteriorRing->vertexAt( id );
370}
371
372QVector<double> QgsTriangle::lengths() const
373{
374 QVector<double> lengths;
375 if ( isEmpty() )
376 return lengths;
377
378 lengths.append( vertexAt( 0 ).distance( vertexAt( 1 ) ) ); // c = |AB|
379 lengths.append( vertexAt( 1 ).distance( vertexAt( 2 ) ) ); // a = |BC|
380 lengths.append( vertexAt( 0 ).distance( vertexAt( 2 ) ) ); // b = |AC|
381
382 return lengths;
383}
384
385QVector<double> QgsTriangle::angles() const
386{
387 QVector<double> angles;
388 if ( isEmpty() )
389 return angles;
390
391 QVector<double> l = lengths();
392
393 const double a = l[1];
394 const double b = l[2];
395 const double c = l[0];
396
397 const double a2 = a * a;
398 const double b2 = b * b;
399 const double c2 = c * c;
400
401 const double alpha = acos( ( b2 + c2 - a2 ) / ( 2 * b * c ) );
402 const double beta = acos( ( a2 + c2 - b2 ) / ( 2 * a * c ) );
403 const double gamma = M_PI - alpha - beta; // acos((a2 + b2 - c2)/(2*a*b)); but ensure that alpha+beta+gamma = 180.0
404
405 angles.append( alpha );
406 angles.append( beta );
407 angles.append( gamma );
408
409 return angles;
410}
411
413{
414 if ( isEmpty() )
415 return true;
416
417 const QgsPoint p1( vertexAt( 0 ) );
418 const QgsPoint p2( vertexAt( 1 ) );
419 const QgsPoint p3( vertexAt( 2 ) );
420 return ( ( ( p1 == p2 ) || ( p1 == p3 ) || ( p2 == p3 ) ) || QgsGeometryUtilsBase::leftOfLine( p1.x(), p1.y(), p2.x(), p2.y(), p3.x(), p3.y() ) == 0 );
421}
422
423bool QgsTriangle::isIsocele( double lengthTolerance ) const
424{
425 if ( isEmpty() )
426 return false;
427 const QVector<double> sides = lengths();
428 const bool ab_bc = qgsDoubleNear( sides.at( 0 ), sides.at( 1 ), lengthTolerance );
429 const bool bc_ca = qgsDoubleNear( sides.at( 1 ), sides.at( 2 ), lengthTolerance );
430 const bool ca_ab = qgsDoubleNear( sides.at( 2 ), sides.at( 0 ), lengthTolerance );
431
432 return ( ab_bc || bc_ca || ca_ab );
433}
434
435bool QgsTriangle::isEquilateral( double lengthTolerance ) const
436{
437 if ( isEmpty() )
438 return false;
439 const QVector<double> sides = lengths();
440 const bool ab_bc = qgsDoubleNear( sides.at( 0 ), sides.at( 1 ), lengthTolerance );
441 const bool bc_ca = qgsDoubleNear( sides.at( 1 ), sides.at( 2 ), lengthTolerance );
442 const bool ca_ab = qgsDoubleNear( sides.at( 2 ), sides.at( 0 ), lengthTolerance );
443
444 return ( ab_bc && bc_ca && ca_ab );
445}
446
447bool QgsTriangle::isRight( double angleTolerance ) const
448{
449 if ( isEmpty() )
450 return false;
451 QVector<double> a = angles();
452 QVector<double>::iterator ita = a.begin();
453 while ( ita != a.end() )
454 {
455 if ( qgsDoubleNear( *ita, M_PI_2, angleTolerance ) )
456 return true;
457 ++ita;
458 }
459 return false;
460}
461
462bool QgsTriangle::isScalene( double lengthTolerance ) const
463{
464 if ( isEmpty() )
465 return false;
466 return !isIsocele( lengthTolerance );
467}
468
469QVector<QgsLineString> QgsTriangle::altitudes() const
470{
471 QVector<QgsLineString> alt;
472 if ( isEmpty() )
473 return alt;
474
475 alt.append( QgsGeometryUtils::perpendicularSegment( vertexAt( 0 ), vertexAt( 2 ), vertexAt( 1 ) ) );
476 alt.append( QgsGeometryUtils::perpendicularSegment( vertexAt( 1 ), vertexAt( 0 ), vertexAt( 2 ) ) );
477 alt.append( QgsGeometryUtils::perpendicularSegment( vertexAt( 2 ), vertexAt( 0 ), vertexAt( 1 ) ) );
478
479 return alt;
480}
481
482QVector<QgsLineString> QgsTriangle::medians() const
483{
484 QVector<QgsLineString> med;
485 if ( isEmpty() )
486 return med;
487
488 QgsLineString med1;
489 QgsLineString med2;
490 QgsLineString med3;
494 med.append( med1 );
495 med.append( med2 );
496 med.append( med3 );
497
498 return med;
499}
500
501QVector<QgsLineString> QgsTriangle::bisectors( double lengthTolerance ) const
502{
503 QVector<QgsLineString> bis;
504 if ( isEmpty() )
505 return bis;
506
507 QgsLineString bis1;
508 QgsLineString bis2;
509 QgsLineString bis3;
510 const QgsPoint incenter = inscribedCenter();
511 QgsPoint out;
512 bool intersection = false;
513
514 QgsGeometryUtils::segmentIntersection( vertexAt( 0 ), incenter, vertexAt( 1 ), vertexAt( 2 ), out, intersection, lengthTolerance );
515 bis1.setPoints( QgsPointSequence() << vertexAt( 0 ) << out );
516
517 QgsGeometryUtils::segmentIntersection( vertexAt( 1 ), incenter, vertexAt( 0 ), vertexAt( 2 ), out, intersection, lengthTolerance );
518 bis2.setPoints( QgsPointSequence() << vertexAt( 1 ) << out );
519
520 QgsGeometryUtils::segmentIntersection( vertexAt( 2 ), incenter, vertexAt( 0 ), vertexAt( 1 ), out, intersection, lengthTolerance );
521 bis3.setPoints( QgsPointSequence() << vertexAt( 2 ) << out );
522
523 bis.append( bis1 );
524 bis.append( bis2 );
525 bis.append( bis3 );
526
527 return bis;
528}
529
531{
532 if ( isEmpty() )
533 return QgsTriangle();
534 QgsPoint p1, p2, p3;
538 return QgsTriangle( p1, p2, p3 );
539}
540
541QgsPoint QgsTriangle::orthocenter( double lengthTolerance ) const
542{
543 if ( isEmpty() )
544 return QgsPoint();
545 const QVector<QgsLineString> alt = altitudes();
546 QgsPoint ortho;
547 bool intersection;
548 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 );
549
550 return ortho;
551}
552
554{
555 if ( isEmpty() )
556 return QgsPoint();
557 double r, x, y;
559 return QgsPoint( x, y );
560}
561
563{
564 if ( isEmpty() )
565 return 0.0;
566 double r, x, y;
568 return r;
569}
570
572{
573 if ( isEmpty() )
574 return QgsCircle();
576}
577
579{
580 if ( isEmpty() )
581 return QgsPoint();
582
583 const QVector<double> l = lengths();
584 const double x = ( l.at( 0 ) * vertexAt( 2 ).x() +
585 l.at( 1 ) * vertexAt( 0 ).x() +
586 l.at( 2 ) * vertexAt( 1 ).x() ) / perimeter();
587 const double y = ( l.at( 0 ) * vertexAt( 2 ).y() +
588 l.at( 1 ) * vertexAt( 0 ).y() +
589 l.at( 2 ) * vertexAt( 1 ).y() ) / perimeter();
590
591 QgsPoint center( x, y );
592
593 QgsPointSequence points;
594 points << vertexAt( 0 ) << vertexAt( 1 ) << vertexAt( 2 );
596
597 return center;
598}
599
601{
602 if ( isEmpty() )
603 return 0.0;
604 return ( 2.0 * area() / perimeter() );
605}
606
608{
609 if ( isEmpty() )
610 return QgsCircle();
612}
@ Polygon
Polygons.
Definition qgis.h:361
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:277
@ LineStringM
LineStringM.
Definition qgis.h:311
@ LineString
LineString.
Definition qgis.h:280
@ LineStringZM
LineStringZM.
Definition qgis.h:326
@ TriangleZ
TriangleZ.
Definition qgis.h:298
@ Triangle
Triangle.
Definition qgis.h:282
@ TriangleZM
TriangleZM.
Definition qgis.h:339
@ TriangleM
TriangleM.
Definition qgis.h:313
@ LineStringZ
LineStringZ.
Definition qgis.h:296
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.
virtual QgsPoint vertexAt(QgsVertexId id) const =0
Returns the point corresponding to a specified vertex id.
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:44
A const WKB pointer.
Definition qgswkbptr.h:139
Qgis::WkbType readHeader() const
readHeader
Definition qgswkbptr.cpp:56
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:36
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:176
virtual bool isClosed() const
Returns true if the curve is closed.
Definition qgscurve.cpp:54
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.
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...
Represents a 2D point.
Definition qgspointxy.h:60
double y
Definition qgspointxy.h:64
double x
Definition qgspointxy.h:63
Point geometry type, with support for z-dimension and m-values.
Definition qgspoint.h:49
double z
Definition qgspoint.h:54
double x
Definition qgspoint.h:52
double m
Definition qgspoint.h:55
double y
Definition qgspoint.h:53
void clear() override
Clears the geometry, ie reset it to a null geometry.
friend class QgsCurvePolygon
Definition qgspolygon.h:139
QgsPolygon()
Constructor for an empty polygon geometry.
void clearCache() const override
Clears any cached parameters associated with the geometry, e.g., bounding boxes.
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.
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
QgsPoint inscribedCenter() const
Center of the inscribed circle of the triangle.
bool operator==(const QgsAbstractGeometry &other) const override
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.
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.
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...
QgsPoint vertexAt(QgsVertexId id) const override
Returns the point corresponding to a specified vertex id.
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...
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
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:6607
T qgsgeometry_cast(QgsAbstractGeometry *geom)
QVector< QgsPoint > QgsPointSequence
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