QGIS API Documentation 3.43.0-Master (0bee5d6404c)
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
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
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 auto curvePolygon = std::make_unique<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
365{
366 return QgsPolygon::vertexAt( id );
367}
368
369QgsPoint QgsTriangle::vertexAt( int atVertex ) const
370{
371 if ( isEmpty() )
372 return QgsPoint();
373
374 const QgsVertexId id( 0, 0, atVertex );
375 return mExteriorRing->vertexAt( id );
376}
377
378QVector<double> QgsTriangle::lengths() const
379{
380 QVector<double> lengths;
381 if ( isEmpty() )
382 return lengths;
383
384 lengths.append( vertexAt( 0 ).distance( vertexAt( 1 ) ) ); // c = |AB|
385 lengths.append( vertexAt( 1 ).distance( vertexAt( 2 ) ) ); // a = |BC|
386 lengths.append( vertexAt( 0 ).distance( vertexAt( 2 ) ) ); // b = |AC|
387
388 return lengths;
389}
390
391QVector<double> QgsTriangle::angles() const
392{
393 QVector<double> angles;
394 if ( isEmpty() )
395 return angles;
396
397 QVector<double> l = lengths();
398
399 const double a = l[1];
400 const double b = l[2];
401 const double c = l[0];
402
403 const double a2 = a * a;
404 const double b2 = b * b;
405 const double c2 = c * c;
406
407 const double alpha = acos( ( b2 + c2 - a2 ) / ( 2 * b * c ) );
408 const double beta = acos( ( a2 + c2 - b2 ) / ( 2 * a * c ) );
409 const double gamma = M_PI - alpha - beta; // acos((a2 + b2 - c2)/(2*a*b)); but ensure that alpha+beta+gamma = 180.0
410
411 angles.append( alpha );
412 angles.append( beta );
413 angles.append( gamma );
414
415 return angles;
416}
417
419{
420 if ( isEmpty() )
421 return true;
422
423 const QgsPoint p1( vertexAt( 0 ) );
424 const QgsPoint p2( vertexAt( 1 ) );
425 const QgsPoint p3( vertexAt( 2 ) );
426 return ( ( ( p1 == p2 ) || ( p1 == p3 ) || ( p2 == p3 ) ) || QgsGeometryUtilsBase::leftOfLine( p1.x(), p1.y(), p2.x(), p2.y(), p3.x(), p3.y() ) == 0 );
427}
428
429bool QgsTriangle::isIsocele( double lengthTolerance ) const
430{
431 if ( isEmpty() )
432 return false;
433 const QVector<double> sides = lengths();
434 const bool ab_bc = qgsDoubleNear( sides.at( 0 ), sides.at( 1 ), lengthTolerance );
435 const bool bc_ca = qgsDoubleNear( sides.at( 1 ), sides.at( 2 ), lengthTolerance );
436 const bool ca_ab = qgsDoubleNear( sides.at( 2 ), sides.at( 0 ), lengthTolerance );
437
438 return ( ab_bc || bc_ca || ca_ab );
439}
440
441bool QgsTriangle::isEquilateral( double lengthTolerance ) const
442{
443 if ( isEmpty() )
444 return false;
445 const QVector<double> sides = lengths();
446 const bool ab_bc = qgsDoubleNear( sides.at( 0 ), sides.at( 1 ), lengthTolerance );
447 const bool bc_ca = qgsDoubleNear( sides.at( 1 ), sides.at( 2 ), lengthTolerance );
448 const bool ca_ab = qgsDoubleNear( sides.at( 2 ), sides.at( 0 ), lengthTolerance );
449
450 return ( ab_bc && bc_ca && ca_ab );
451}
452
453bool QgsTriangle::isRight( double angleTolerance ) const
454{
455 if ( isEmpty() )
456 return false;
457 QVector<double> a = angles();
458 QVector<double>::iterator ita = a.begin();
459 while ( ita != a.end() )
460 {
461 if ( qgsDoubleNear( *ita, M_PI_2, angleTolerance ) )
462 return true;
463 ++ita;
464 }
465 return false;
466}
467
468bool QgsTriangle::isScalene( double lengthTolerance ) const
469{
470 if ( isEmpty() )
471 return false;
472 return !isIsocele( lengthTolerance );
473}
474
475QVector<QgsLineString> QgsTriangle::altitudes() const
476{
477 QVector<QgsLineString> alt;
478 if ( isEmpty() )
479 return alt;
480
481 alt.append( QgsGeometryUtils::perpendicularSegment( vertexAt( 0 ), vertexAt( 2 ), vertexAt( 1 ) ) );
482 alt.append( QgsGeometryUtils::perpendicularSegment( vertexAt( 1 ), vertexAt( 0 ), vertexAt( 2 ) ) );
483 alt.append( QgsGeometryUtils::perpendicularSegment( vertexAt( 2 ), vertexAt( 0 ), vertexAt( 1 ) ) );
484
485 return alt;
486}
487
488QVector<QgsLineString> QgsTriangle::medians() const
489{
490 QVector<QgsLineString> med;
491 if ( isEmpty() )
492 return med;
493
494 QgsLineString med1;
495 QgsLineString med2;
496 QgsLineString med3;
500 med.append( med1 );
501 med.append( med2 );
502 med.append( med3 );
503
504 return med;
505}
506
507QVector<QgsLineString> QgsTriangle::bisectors( double lengthTolerance ) const
508{
509 QVector<QgsLineString> bis;
510 if ( isEmpty() )
511 return bis;
512
513 QgsLineString bis1;
514 QgsLineString bis2;
515 QgsLineString bis3;
516 const QgsPoint incenter = inscribedCenter();
517 QgsPoint out;
518 bool intersection = false;
519
520 QgsGeometryUtils::segmentIntersection( vertexAt( 0 ), incenter, vertexAt( 1 ), vertexAt( 2 ), out, intersection, lengthTolerance );
521 bis1.setPoints( QgsPointSequence() << vertexAt( 0 ) << out );
522
523 QgsGeometryUtils::segmentIntersection( vertexAt( 1 ), incenter, vertexAt( 0 ), vertexAt( 2 ), out, intersection, lengthTolerance );
524 bis2.setPoints( QgsPointSequence() << vertexAt( 1 ) << out );
525
526 QgsGeometryUtils::segmentIntersection( vertexAt( 2 ), incenter, vertexAt( 0 ), vertexAt( 1 ), out, intersection, lengthTolerance );
527 bis3.setPoints( QgsPointSequence() << vertexAt( 2 ) << out );
528
529 bis.append( bis1 );
530 bis.append( bis2 );
531 bis.append( bis3 );
532
533 return bis;
534}
535
537{
538 if ( isEmpty() )
539 return QgsTriangle();
540 QgsPoint p1, p2, p3;
544 return QgsTriangle( p1, p2, p3 );
545}
546
547QgsPoint QgsTriangle::orthocenter( double lengthTolerance ) const
548{
549 if ( isEmpty() )
550 return QgsPoint();
551 const QVector<QgsLineString> alt = altitudes();
552 QgsPoint ortho;
553 bool intersection;
554 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 );
555
556 return ortho;
557}
558
560{
561 if ( isEmpty() )
562 return QgsPoint();
563 double r, x, y;
565 return QgsPoint( x, y );
566}
567
569{
570 if ( isEmpty() )
571 return 0.0;
572 double r, x, y;
574 return r;
575}
576
578{
579 if ( isEmpty() )
580 return QgsCircle();
582}
583
585{
586 if ( isEmpty() )
587 return QgsPoint();
588
589 const QVector<double> l = lengths();
590 const double x = ( l.at( 0 ) * vertexAt( 2 ).x() +
591 l.at( 1 ) * vertexAt( 0 ).x() +
592 l.at( 2 ) * vertexAt( 1 ).x() ) / perimeter();
593 const double y = ( l.at( 0 ) * vertexAt( 2 ).y() +
594 l.at( 1 ) * vertexAt( 0 ).y() +
595 l.at( 2 ) * vertexAt( 1 ).y() ) / perimeter();
596
597 QgsPoint center( x, y );
598
599 QgsPointSequence points;
600 points << vertexAt( 0 ) << vertexAt( 1 ) << vertexAt( 2 );
602
603 return center;
604}
605
607{
608 if ( isEmpty() )
609 return 0.0;
610 return ( 2.0 * area() / perimeter() );
611}
612
614{
615 if ( isEmpty() )
616 return QgsCircle();
618}
@ Polygon
Polygons.
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:256
@ 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.
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:45
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
QgsCurve * clone() const override=0
Clones the geometry by performing a deep copy.
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
Polygon geometry type.
Definition qgspolygon.h:33
void clear() override
Clears the geometry, ie reset it to a null geometry.
void clearCache() const override
Clears any cached parameters associated with the geometry, e.g., bounding boxes.
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.
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:6287
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