QGIS API Documentation  3.18.1-Zürich (202f1bf7e5)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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 
30 QgsTriangle::QgsTriangle( const QgsPoint &p1, const QgsPoint &p2, const QgsPoint &p3 )
31 {
33 
34  QVector< double > x { p1.x(), p2.x(), p3.x(), p1.x() };
35  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 
49 QgsTriangle::QgsTriangle( const QgsPointXY &p1, const QgsPointXY &p2, const QgsPointXY &p3 )
50 {
52 
53  QVector< double > x { p1.x(), p2.x(), p3.x(), p1.x() };
54  QVector< double > y {p1.y(), p2.y(), p3.y(), p1.y() };
55  QgsLineString *ext = new QgsLineString( x, y );
56  setExteriorRing( ext );
57 }
58 
59 QgsTriangle::QgsTriangle( const QPointF p1, const QPointF p2, const QPointF p3 )
60 {
62 
63  QVector< double > x{ p1.x(), p2.x(), p3.x(), p1.x() };
64  QVector< double > y{ p1.y(), p2.y(), p3.y(), p1.y() };
65  QgsLineString *ext = new QgsLineString( x, y );
66  setExteriorRing( ext );
67 }
68 
69 bool QgsTriangle::operator==( const QgsTriangle &other ) const
70 {
71  if ( isEmpty() && other.isEmpty() )
72  {
73  return true;
74  }
75  else if ( isEmpty() || other.isEmpty() )
76  {
77  return false;
78  }
79 
80  return ( ( vertexAt( 0 ) == other.vertexAt( 0 ) ) &&
81  ( vertexAt( 1 ) == other.vertexAt( 1 ) ) &&
82  ( vertexAt( 2 ) == other.vertexAt( 2 ) )
83  );
84 }
85 
86 bool QgsTriangle::operator!=( const QgsTriangle &other ) const
87 {
88  return !operator==( other );
89 }
90 
92 {
93  return QStringLiteral( "Triangle" );
94 }
95 
97 {
98  auto result = qgis::make_unique< QgsTriangle >();
99  result->mWkbType = mWkbType;
100  return result.release();
101 }
102 
104 {
107 }
108 
110 {
111  return new QgsTriangle( *this );
112 }
113 
115 {
116  clear();
117  if ( !wkbPtr )
118  {
119  return false;
120  }
121 
122  QgsWkbTypes::Type type = wkbPtr.readHeader();
124  {
125  return false;
126  }
127  mWkbType = type;
128 
129  QgsWkbTypes::Type ringType;
130  switch ( mWkbType )
131  {
133  ringType = QgsWkbTypes::LineStringZ;
134  break;
136  ringType = QgsWkbTypes::LineStringM;
137  break;
139  ringType = QgsWkbTypes::LineStringZM;
140  break;
141  default:
142  ringType = QgsWkbTypes::LineString;
143  break;
144  }
145 
146  int nRings;
147  wkbPtr >> nRings;
148  if ( nRings > 1 )
149  {
150  return false;
151  }
152 
153  QgsLineString *line = new QgsLineString();
154  line->fromWkbPoints( ringType, wkbPtr );
155  mExteriorRing.reset( line );
156 
157  return true;
158 }
159 
160 bool QgsTriangle::fromWkt( const QString &wkt )
161 {
162  clear();
163 
164  QPair<QgsWkbTypes::Type, QString> parts = QgsGeometryUtils::wktReadBlock( wkt );
165 
167  return false;
168 
169  mWkbType = parts.first;
170 
171  QString secondWithoutParentheses = parts.second;
172  secondWithoutParentheses = secondWithoutParentheses.simplified().remove( ' ' );
173  if ( ( parts.second.compare( QLatin1String( "EMPTY" ), Qt::CaseInsensitive ) == 0 ) ||
174  secondWithoutParentheses.isEmpty() )
175  return true;
176 
177  QString defaultChildWkbType = QStringLiteral( "LineString%1%2" ).arg( is3D() ? QStringLiteral( "Z" ) : QString(), isMeasure() ? QStringLiteral( "M" ) : QString() );
178 
179  const QStringList blocks = QgsGeometryUtils::wktGetChildBlocks( parts.second, defaultChildWkbType );
180  for ( const QString &childWkt : blocks )
181  {
182  QPair<QgsWkbTypes::Type, QString> childParts = QgsGeometryUtils::wktReadBlock( childWkt );
183 
184  QgsWkbTypes::Type flatCurveType = QgsWkbTypes::flatType( childParts.first );
185  if ( flatCurveType == QgsWkbTypes::LineString )
186  mInteriorRings.append( new QgsLineString() );
187  else
188  {
189  clear();
190  return false;
191  }
192  if ( !mInteriorRings.back()->fromWkt( childWkt ) )
193  {
194  clear();
195  return false;
196  }
197  }
198 
199  if ( mInteriorRings.isEmpty() )
200  {
201  clear();
202  return false;
203  }
204  mExteriorRing.reset( mInteriorRings.takeFirst() );
205  if ( ( mExteriorRing->numPoints() < 3 ) || ( mExteriorRing->numPoints() > 4 ) || ( mExteriorRing->numPoints() == 4 && mExteriorRing->startPoint() != mExteriorRing->endPoint() ) )
206  {
207  clear();
208  return false;
209  }
210 
211  //scan through rings and check if dimensionality of rings is different to CurvePolygon.
212  //if so, update the type dimensionality of the CurvePolygon to match
213  bool hasZ = false;
214  bool hasM = false;
215  if ( mExteriorRing )
216  {
217  hasZ = hasZ || mExteriorRing->is3D();
218  hasM = hasM || mExteriorRing->isMeasure();
219  }
220  if ( hasZ )
221  addZValue( 0 );
222  if ( hasM )
223  addMValue( 0 );
224 
225  return true;
226 }
227 
228 QDomElement QgsTriangle::asGml3( QDomDocument &doc, int precision, const QString &ns, const AxisOrder axisOrder ) const
229 {
230 
231  QDomElement elemTriangle = doc.createElementNS( ns, QStringLiteral( "Triangle" ) );
232 
233  if ( isEmpty() )
234  return elemTriangle;
235 
236  QDomElement elemExterior = doc.createElementNS( ns, QStringLiteral( "exterior" ) );
237  QDomElement curveElem = exteriorRing()->asGml3( doc, precision, ns, axisOrder );
238  if ( curveElem.tagName() == QLatin1String( "LineString" ) )
239  {
240  curveElem.setTagName( QStringLiteral( "LinearRing" ) );
241  }
242  elemExterior.appendChild( curveElem );
243  elemTriangle.appendChild( elemExterior );
244 
245  return elemTriangle;
246 }
247 
249 {
250  return toPolygon();
251 }
252 
254 {
255  std::unique_ptr<QgsCurvePolygon> curvePolygon( new QgsCurvePolygon() );
256  curvePolygon->setExteriorRing( mExteriorRing->clone() );
257 
258  return curvePolygon.release();
259 }
260 
262 {
263  delete ring;
264 }
265 
267 {
268  Q_UNUSED( position )
269  return false;
270 }
271 
272 bool QgsTriangle::insertVertex( QgsVertexId position, const QgsPoint &vertex )
273 {
274  Q_UNUSED( position )
275  Q_UNUSED( vertex )
276  return false;
277 }
278 
279 bool QgsTriangle::moveVertex( QgsVertexId vId, const QgsPoint &newPos )
280 {
281  if ( isEmpty() )
282  return false;
283 
284  if ( !mExteriorRing || vId.part != 0 || vId.ring != 0 || vId.vertex < 0 || vId.vertex > 4 )
285  {
286  return false;
287  }
288 
289  if ( vId.vertex == 4 )
290  {
291  vId.vertex = 0;
292  }
293 
294  int n = mExteriorRing->numPoints();
295  bool success = mExteriorRing->moveVertex( vId, newPos );
296  if ( success )
297  {
298  // If first or last vertex is moved, also move the last/first vertex
299  if ( vId.vertex == 0 )
300  mExteriorRing->moveVertex( QgsVertexId( vId.part, vId.ring, n - 1 ), newPos );
301  clearCache();
302  }
303  return success;
304 }
305 
307 {
308  if ( !ring )
309  {
310  return;
311  }
312 
313  if ( ring->hasCurvedSegments() )
314  {
315  //need to segmentize ring as polygon does not support curves
316  QgsCurve *line = ring->segmentize();
317  delete ring;
318  ring = line;
319  }
320 
321  if ( ( ring->numPoints() > 4 ) || ( ring->numPoints() < 3 ) )
322  {
323  delete ring;
324  return;
325  }
326  else if ( ring->numPoints() == 4 )
327  {
328  if ( !ring->isClosed() )
329  {
330  delete ring;
331  return;
332  }
333  }
334  else if ( ring->numPoints() == 3 )
335  {
336  if ( ring->isClosed() )
337  {
338  delete ring;
339  return;
340  }
341  QgsLineString *lineString = static_cast< QgsLineString *>( ring );
342  if ( !lineString->isClosed() )
343  {
344  lineString->close();
345  }
346  ring = lineString;
347  }
348 
349  mExteriorRing.reset( ring );
350 
351  //set proper wkb type
353 
354  clearCache();
355 }
356 
358 {
359  if ( !mExteriorRing )
360  return nullptr;
361 
362  return mExteriorRing->clone();
363 }
364 
365 QgsPoint QgsTriangle::vertexAt( int atVertex ) const
366 {
367  if ( isEmpty() )
368  return QgsPoint();
369 
370  QgsVertexId id( 0, 0, atVertex );
371  return mExteriorRing->vertexAt( id );
372 }
373 
374 QVector<double> QgsTriangle::lengths() const
375 {
376  QVector<double> lengths;
377  if ( isEmpty() )
378  return lengths;
379 
380  lengths.append( vertexAt( 0 ).distance( vertexAt( 1 ) ) );
381  lengths.append( vertexAt( 1 ).distance( vertexAt( 2 ) ) );
382  lengths.append( vertexAt( 2 ).distance( vertexAt( 0 ) ) );
383 
384  return lengths;
385 }
386 
387 QVector<double> QgsTriangle::angles() const
388 {
389  QVector<double> angles;
390  if ( isEmpty() )
391  return angles;
392  double ax, ay, bx, by, cx, cy;
393 
394  ax = vertexAt( 0 ).x();
395  ay = vertexAt( 0 ).y();
396  bx = vertexAt( 1 ).x();
397  by = vertexAt( 1 ).y();
398  cx = vertexAt( 2 ).x();
399  cy = vertexAt( 2 ).y();
400 
401  double a1 = std::fmod( QgsGeometryUtils::angleBetweenThreePoints( cx, cy, ax, ay, bx, by ), M_PI );
402  double a2 = std::fmod( QgsGeometryUtils::angleBetweenThreePoints( ax, ay, bx, by, cx, cy ), M_PI );
403  double a3 = std::fmod( QgsGeometryUtils::angleBetweenThreePoints( bx, by, cx, cy, ax, ay ), M_PI );
404 
405  angles.append( ( a1 > M_PI_2 ? a1 - M_PI_2 : a1 ) );
406  angles.append( ( a2 > M_PI_2 ? a2 - M_PI_2 : a2 ) );
407  angles.append( ( a3 > M_PI_2 ? a3 - M_PI_2 : a3 ) );
408 
409  return angles;
410 }
411 
413 {
414  if ( isEmpty() )
415  return true;
416 
417  QgsPoint p1( vertexAt( 0 ) );
418  QgsPoint p2( vertexAt( 1 ) );
419  QgsPoint p3( vertexAt( 2 ) );
420  return ( ( ( p1 == p2 ) || ( p1 == p3 ) || ( p2 == p3 ) ) || QgsGeometryUtils::leftOfLine( p1.x(), p1.y(), p2.x(), p2.y(), p3.x(), p3.y() ) == 0 );
421 }
422 
423 bool QgsTriangle::isIsocele( double lengthTolerance ) const
424 {
425  if ( isEmpty() )
426  return false;
427  QVector<double> sides = lengths();
428  bool ab_bc = qgsDoubleNear( sides.at( 0 ), sides.at( 1 ), lengthTolerance );
429  bool bc_ca = qgsDoubleNear( sides.at( 1 ), sides.at( 2 ), lengthTolerance );
430  bool ca_ab = qgsDoubleNear( sides.at( 2 ), sides.at( 0 ), lengthTolerance );
431 
432  return ( ab_bc || bc_ca || ca_ab );
433 }
434 
435 bool QgsTriangle::isEquilateral( double lengthTolerance ) const
436 {
437  if ( isEmpty() )
438  return false;
439  QVector<double> sides = lengths();
440  bool ab_bc = qgsDoubleNear( sides.at( 0 ), sides.at( 1 ), lengthTolerance );
441  bool bc_ca = qgsDoubleNear( sides.at( 1 ), sides.at( 2 ), lengthTolerance );
442  bool ca_ab = qgsDoubleNear( sides.at( 2 ), sides.at( 0 ), lengthTolerance );
443 
444  return ( ab_bc && bc_ca && ca_ab );
445 }
446 
447 bool 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 
462 bool QgsTriangle::isScalene( double lengthTolerance ) const
463 {
464  if ( isEmpty() )
465  return false;
466  return !isIsocele( lengthTolerance );
467 }
468 
469 QVector<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 
482 QVector<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 
501 QVector<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  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;
535  p1 = QgsGeometryUtils::midpoint( vertexAt( 0 ), vertexAt( 1 ) );
536  p2 = QgsGeometryUtils::midpoint( vertexAt( 1 ), vertexAt( 2 ) );
537  p3 = QgsGeometryUtils::midpoint( vertexAt( 2 ), vertexAt( 0 ) );
538  return QgsTriangle( p1, p2, p3 );
539 }
540 
541 QgsPoint QgsTriangle::orthocenter( double lengthTolerance ) const
542 {
543  if ( isEmpty() )
544  return QgsPoint();
545  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;
558  QgsGeometryUtils::circleCenterRadius( vertexAt( 0 ), vertexAt( 1 ), vertexAt( 2 ), r, x, y );
559  return QgsPoint( x, y );
560 }
561 
563 {
564  if ( isEmpty() )
565  return 0.0;
566  double r, x, y;
567  QgsGeometryUtils::circleCenterRadius( vertexAt( 0 ), vertexAt( 1 ), vertexAt( 2 ), 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  QVector<double> l = lengths();
584  double x = ( l.at( 0 ) * vertexAt( 2 ).x() +
585  l.at( 1 ) * vertexAt( 0 ).x() +
586  l.at( 2 ) * vertexAt( 1 ).x() ) / perimeter();
587  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 );
595  QgsGeometryUtils::setZValueFromPoints( points, center );
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 }
bool is3D() const SIP_HOLDGIL
Returns true if the geometry is 3D and contains a z-value.
AxisOrder
Axis order for GML generation.
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.
QgsWkbTypes::Type mWkbType
QgsGeometryConstPartIterator parts() const
Returns Java-style iterator for traversal of parts of the geometry.
bool isMeasure() const SIP_HOLDGIL
Returns true if the geometry contains m values.
void setZMTypeFromSubGeometry(const QgsAbstractGeometry *subggeom, QgsWkbTypes::Type baseGeomType)
Updates the geometry type based on whether sub geometries contain z or m values.
Circle geometry type.
Definition: qgscircle.h:44
A const WKB pointer.
Definition: qgswkbptr.h:130
QgsWkbTypes::Type readHeader() const
readHeader
Definition: qgswkbptr.cpp:54
Curve polygon geometry type.
bool isEmpty() const override SIP_HOLDGIL
Returns true if the geometry is empty.
bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value.
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
bool addMValue(double mValue=0) override
Adds a measure to the geometry, initialized to a preset value.
double area() const override SIP_HOLDGIL
Returns the planar, 2-dimensional area of the geometry.
const QgsCurve * exteriorRing() const SIP_HOLDGIL
Returns the curve polygon's exterior ring.
double perimeter() const override SIP_HOLDGIL
Returns the planar, 2-dimensional perimeter of the geometry.
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:166
virtual bool isClosed() const SIP_HOLDGIL
Returns true if the curve is closed.
Definition: qgscurve.cpp:40
static QPair< QgsWkbTypes::Type, QString > wktReadBlock(const QString &wkt)
Parses a WKT block of the format "TYPE( contents )" and returns a pair of geometry type to contents (...
static QgsPoint midpoint(const QgsPoint &pt1, const QgsPoint &pt2) SIP_HOLDGIL
Returns a middle point between points pt1 and pt2.
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 setZValueFromPoints(const QgsPointSequence &points, QgsPoint &point)
A Z dimension is added to point if one of the point in the list points is in 3D.
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) SIP_HOLDGIL
Compute the intersection between two segments.
static void circleCenterRadius(const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double &radius, double &centerX, double &centerY) SIP_HOLDGIL
Returns radius and center of the circle through pt1, pt2, pt3.
static double angleBetweenThreePoints(double x1, double y1, double x2, double y2, double x3, double y3) SIP_HOLDGIL
Calculates the angle between the lines AB and BC, where AB and BC described by points a,...
static QgsLineString perpendicularSegment(const QgsPoint &p, const QgsPoint &s1, const QgsPoint &s2) SIP_HOLDGIL
Create a perpendicular line segment from p to segment [s1, s2].
static int leftOfLine(const double x, const double y, const double x1, const double y1, const double x2, const double y2) SIP_HOLDGIL
Returns a value < 0 if the point (x, y) is left of the line from (x1, y1) -> (x2, y2).
Line string geometry type, with support for z-dimension and m-values.
Definition: qgslinestring.h:44
void setPoints(const QgsPointSequence &points)
Resets the line string to match the specified list of points.
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:44
double y
Definition: qgspointxy.h:48
Q_GADGET double x
Definition: qgspointxy.h:47
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:38
Q_GADGET double x
Definition: qgspoint.h:41
double z
Definition: qgspoint.h:43
double m
Definition: qgspoint.h:44
double y
Definition: qgspoint.h:42
Polygon geometry type.
Definition: qgspolygon.h:34
void clear() override
Clears the geometry, ie reset it to a null geometry.
Definition: qgspolygon.cpp:59
friend class QgsCurvePolygon
Definition: qgspolygon.h:118
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:34
QgsTriangle medial() const SIP_HOLDGIL
Medial (or midpoint) triangle of a triangle ABC is the triangle with vertices at the midpoints of the...
bool fromWkt(const QString &wkt) override
Sets the geometry from a WKT string.
QgsPolygon * surfaceToPolygon() const override
Gets a polygon representation of this surface.
bool isEquilateral(double lengthTolerance=0.0001) const SIP_HOLDGIL
Is the triangle equilateral (three sides with the same length)?
void clear() override
Clears the geometry, ie reset it to a null geometry.
bool operator==(const QgsTriangle &other) const SIP_HOLDGIL
Definition: qgstriangle.cpp:69
void setExteriorRing(QgsCurve *ring) override
Sets the exterior ring of the polygon.
QgsCurve * boundary() const override
Returns the closure of the combinatorial boundary of the geometry (ie the topological boundary of the...
QVector< double > angles() const SIP_HOLDGIL
Returns the three angles of the triangle.
QgsPoint circumscribedCenter() const SIP_HOLDGIL
Center of the circumscribed circle 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:96
bool deleteVertex(QgsVertexId position) override
Inherited method not used. You cannot delete or insert a vertex directly. Returns always false.
QgsTriangle * clone() const override
Clones the geometry by performing a deep copy.
QgsCircle circumscribedCircle() const SIP_HOLDGIL
Circumscribed circle of the triangle.
bool isDegenerate() SIP_HOLDGIL
Convenient method checking if the geometry is degenerate (have duplicate or colinear point(s)).
bool isRight(double angleTolerance=0.0001) const SIP_HOLDGIL
Is the triangle right-angled?
bool moveVertex(QgsVertexId vId, const QgsPoint &newPos) override
Moves a vertex within the geometry.
bool operator!=(const QgsTriangle &other) const SIP_HOLDGIL
Definition: qgstriangle.cpp:86
QgsCircle inscribedCircle() const SIP_HOLDGIL
Inscribed circle of the triangle.
QgsCurvePolygon * toCurveType() const override
Returns the geometry converted to the more generic curve type QgsCurvePolygon.
bool isScalene(double lengthTolerance=0.0001) const SIP_HOLDGIL
Is the triangle scalene (all sides have different lengths)?
void addInteriorRing(QgsCurve *ring) override
Inherited method not used. You cannot add an interior ring into a triangle.
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.
QgsPoint vertexAt(int atVertex) const SIP_HOLDGIL
Returns coordinates of a vertex.
bool insertVertex(QgsVertexId position, const QgsPoint &vertex) override
Inherited method not used. You cannot delete or insert a vertex directly. Returns always false.
QVector< QgsLineString > bisectors(double lengthTolerance=0.0001) const SIP_HOLDGIL
The segment (defined by a QgsLineString) returned bisect the angle of a vertex to the opposite side.
QgsPoint orthocenter(double lengthTolerance=0.0001) const SIP_HOLDGIL
An orthocenter is the point of intersection of the altitudes of a triangle.
double inscribedRadius() const SIP_HOLDGIL
Radius of the inscribed circle of the triangle.
QString geometryType() const override SIP_HOLDGIL
Returns a unique string representing the geometry type.
Definition: qgstriangle.cpp:91
QgsPoint inscribedCenter() const SIP_HOLDGIL
Center of the inscribed circle of the triangle.
QVector< QgsLineString > altitudes() const SIP_HOLDGIL
An altitude is a segment (defined by a QgsLineString) from a vertex to the opposite side (or,...
double circumscribedRadius() const SIP_HOLDGIL
Radius of the circumscribed circle of the triangle.
QgsTriangle() SIP_HOLDGIL
Constructor for an empty triangle geometry.
Definition: qgstriangle.cpp:25
QVector< double > lengths() const SIP_HOLDGIL
Returns the three lengths of the triangle.
QVector< QgsLineString > medians() const SIP_HOLDGIL
A median is a segment (defined by a QgsLineString) from a vertex to the midpoint of the opposite side...
bool isIsocele(double lengthTolerance=0.0001) const SIP_HOLDGIL
Is the triangle isocele (two sides with the same length)?
bool fromWkb(QgsConstWkbPtr &wkbPtr) override
Sets the geometry from a WKB string.
static GeometryType geometryType(Type type) SIP_HOLDGIL
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
Definition: qgswkbtypes.h:938
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:70
static Type flatType(Type type) SIP_HOLDGIL
Returns the flat type for a WKB type.
Definition: qgswkbtypes.h:702
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:316
QVector< QgsPoint > QgsPointSequence
int precision
Utility class for identifying a unique vertex within a geometry.
int vertex
Vertex number.
int part
Part number.
int ring
Ring number.