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