QGIS API Documentation  3.21.0-Master (909859188c)
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  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 
49 QgsTriangle::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 
59 QgsTriangle::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 
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 = std::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  const 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  const 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  const 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  const QPair<QgsWkbTypes::Type, QString> childParts = QgsGeometryUtils::wktReadBlock( childWkt );
183 
184  const QgsWkbTypes::Type flatCurveType = QgsWkbTypes::flatType( childParts.first );
185 
186  if ( flatCurveType == QgsWkbTypes::LineString )
187  mInteriorRings.append( new QgsLineString() );
188  else
189  {
190  clear();
191  return false;
192  }
193  if ( !mInteriorRings.back()->fromWkt( childWkt ) )
194  {
195  clear();
196  return false;
197  }
198  }
199 
200  mExteriorRing.reset( mInteriorRings.takeFirst() );
201  if ( ( mExteriorRing->numPoints() < 3 ) || ( mExteriorRing->numPoints() > 4 ) || ( mExteriorRing->numPoints() == 4 && mExteriorRing->startPoint() != mExteriorRing->endPoint() ) )
202  {
203  clear();
204  return false;
205  }
206 
207  //scan through rings and check if dimensionality of rings is different to CurvePolygon.
208  //if so, update the type dimensionality of the CurvePolygon to match
209  bool hasZ = false;
210  bool hasM = false;
211  if ( mExteriorRing )
212  {
213  hasZ = hasZ || mExteriorRing->is3D();
214  hasM = hasM || mExteriorRing->isMeasure();
215  }
216  if ( hasZ )
217  addZValue( 0 );
218  if ( hasM )
219  addMValue( 0 );
220 
221  return true;
222 }
223 
224 QDomElement QgsTriangle::asGml3( QDomDocument &doc, int precision, const QString &ns, const AxisOrder axisOrder ) const
225 {
226 
227  QDomElement elemTriangle = doc.createElementNS( ns, QStringLiteral( "Triangle" ) );
228 
229  if ( isEmpty() )
230  return elemTriangle;
231 
232  QDomElement elemExterior = doc.createElementNS( ns, QStringLiteral( "exterior" ) );
233  QDomElement curveElem = exteriorRing()->asGml3( doc, precision, ns, axisOrder );
234  if ( curveElem.tagName() == QLatin1String( "LineString" ) )
235  {
236  curveElem.setTagName( QStringLiteral( "LinearRing" ) );
237  }
238  elemExterior.appendChild( curveElem );
239  elemTriangle.appendChild( elemExterior );
240 
241  return elemTriangle;
242 }
243 
245 {
246  return toPolygon();
247 }
248 
250 {
251  std::unique_ptr<QgsCurvePolygon> curvePolygon( new QgsCurvePolygon() );
252  curvePolygon->setExteriorRing( mExteriorRing->clone() );
253 
254  return curvePolygon.release();
255 }
256 
258 {
259  delete ring;
260 }
261 
263 {
264  Q_UNUSED( position )
265  return false;
266 }
267 
268 bool QgsTriangle::insertVertex( QgsVertexId position, const QgsPoint &vertex )
269 {
270  Q_UNUSED( position )
271  Q_UNUSED( vertex )
272  return false;
273 }
274 
275 bool QgsTriangle::moveVertex( QgsVertexId vId, const QgsPoint &newPos )
276 {
277  if ( isEmpty() )
278  return false;
279 
280  if ( !mExteriorRing || vId.part != 0 || vId.ring != 0 || vId.vertex < 0 || vId.vertex > 4 )
281  {
282  return false;
283  }
284 
285  if ( vId.vertex == 4 )
286  {
287  vId.vertex = 0;
288  }
289 
290  const int n = mExteriorRing->numPoints();
291  const bool success = mExteriorRing->moveVertex( vId, newPos );
292  if ( success )
293  {
294  // If first or last vertex is moved, also move the last/first vertex
295  if ( vId.vertex == 0 )
296  mExteriorRing->moveVertex( QgsVertexId( vId.part, vId.ring, n - 1 ), newPos );
297  clearCache();
298  }
299  return success;
300 }
301 
303 {
304  if ( !ring )
305  {
306  return;
307  }
308 
309  if ( ring->hasCurvedSegments() )
310  {
311  //need to segmentize ring as polygon does not support curves
312  QgsCurve *line = ring->segmentize();
313  delete ring;
314  ring = line;
315  }
316 
317  if ( ( ring->numPoints() > 4 ) || ( ring->numPoints() < 3 ) )
318  {
319  delete ring;
320  return;
321  }
322  else if ( ring->numPoints() == 4 )
323  {
324  if ( !ring->isClosed() )
325  {
326  delete ring;
327  return;
328  }
329  }
330  else if ( ring->numPoints() == 3 )
331  {
332  if ( ring->isClosed() )
333  {
334  delete ring;
335  return;
336  }
337  QgsLineString *lineString = static_cast< QgsLineString *>( ring );
338  if ( !lineString->isClosed() )
339  {
340  lineString->close();
341  }
342  ring = lineString;
343  }
344 
345  mExteriorRing.reset( ring );
346 
347  //set proper wkb type
349 
350  clearCache();
351 }
352 
354 {
355  if ( !mExteriorRing )
356  return nullptr;
357 
358  return mExteriorRing->clone();
359 }
360 
361 QgsPoint QgsTriangle::vertexAt( int atVertex ) const
362 {
363  if ( isEmpty() )
364  return QgsPoint();
365 
366  const QgsVertexId id( 0, 0, atVertex );
367  return mExteriorRing->vertexAt( id );
368 }
369 
370 QVector<double> QgsTriangle::lengths() const
371 {
372  QVector<double> lengths;
373  if ( isEmpty() )
374  return lengths;
375 
376  lengths.append( vertexAt( 0 ).distance( vertexAt( 1 ) ) );
377  lengths.append( vertexAt( 1 ).distance( vertexAt( 2 ) ) );
378  lengths.append( vertexAt( 2 ).distance( vertexAt( 0 ) ) );
379 
380  return lengths;
381 }
382 
383 QVector<double> QgsTriangle::angles() const
384 {
385  QVector<double> angles;
386  if ( isEmpty() )
387  return angles;
388  double ax, ay, bx, by, cx, cy;
389 
390  ax = vertexAt( 0 ).x();
391  ay = vertexAt( 0 ).y();
392  bx = vertexAt( 1 ).x();
393  by = vertexAt( 1 ).y();
394  cx = vertexAt( 2 ).x();
395  cy = vertexAt( 2 ).y();
396 
397  const double a1 = std::fmod( QgsGeometryUtils::angleBetweenThreePoints( cx, cy, ax, ay, bx, by ), M_PI );
398  const double a2 = std::fmod( QgsGeometryUtils::angleBetweenThreePoints( ax, ay, bx, by, cx, cy ), M_PI );
399  const double a3 = std::fmod( QgsGeometryUtils::angleBetweenThreePoints( bx, by, cx, cy, ax, ay ), M_PI );
400 
401  angles.append( ( a1 > M_PI_2 ? a1 - M_PI_2 : a1 ) );
402  angles.append( ( a2 > M_PI_2 ? a2 - M_PI_2 : a2 ) );
403  angles.append( ( a3 > M_PI_2 ? a3 - M_PI_2 : a3 ) );
404 
405  return angles;
406 }
407 
409 {
410  if ( isEmpty() )
411  return true;
412 
413  const QgsPoint p1( vertexAt( 0 ) );
414  const QgsPoint p2( vertexAt( 1 ) );
415  const QgsPoint p3( vertexAt( 2 ) );
416  return ( ( ( p1 == p2 ) || ( p1 == p3 ) || ( p2 == p3 ) ) || QgsGeometryUtils::leftOfLine( p1.x(), p1.y(), p2.x(), p2.y(), p3.x(), p3.y() ) == 0 );
417 }
418 
419 bool QgsTriangle::isIsocele( double lengthTolerance ) const
420 {
421  if ( isEmpty() )
422  return false;
423  const QVector<double> sides = lengths();
424  const bool ab_bc = qgsDoubleNear( sides.at( 0 ), sides.at( 1 ), lengthTolerance );
425  const bool bc_ca = qgsDoubleNear( sides.at( 1 ), sides.at( 2 ), lengthTolerance );
426  const bool ca_ab = qgsDoubleNear( sides.at( 2 ), sides.at( 0 ), lengthTolerance );
427 
428  return ( ab_bc || bc_ca || ca_ab );
429 }
430 
431 bool QgsTriangle::isEquilateral( double lengthTolerance ) const
432 {
433  if ( isEmpty() )
434  return false;
435  const QVector<double> sides = lengths();
436  const bool ab_bc = qgsDoubleNear( sides.at( 0 ), sides.at( 1 ), lengthTolerance );
437  const bool bc_ca = qgsDoubleNear( sides.at( 1 ), sides.at( 2 ), lengthTolerance );
438  const bool ca_ab = qgsDoubleNear( sides.at( 2 ), sides.at( 0 ), lengthTolerance );
439 
440  return ( ab_bc && bc_ca && ca_ab );
441 }
442 
443 bool QgsTriangle::isRight( double angleTolerance ) const
444 {
445  if ( isEmpty() )
446  return false;
447  QVector<double> a = angles();
448  QVector<double>::iterator ita = a.begin();
449  while ( ita != a.end() )
450  {
451  if ( qgsDoubleNear( *ita, M_PI_2, angleTolerance ) )
452  return true;
453  ++ita;
454  }
455  return false;
456 }
457 
458 bool QgsTriangle::isScalene( double lengthTolerance ) const
459 {
460  if ( isEmpty() )
461  return false;
462  return !isIsocele( lengthTolerance );
463 }
464 
465 QVector<QgsLineString> QgsTriangle::altitudes() const
466 {
467  QVector<QgsLineString> alt;
468  if ( isEmpty() )
469  return alt;
470 
471  alt.append( QgsGeometryUtils::perpendicularSegment( vertexAt( 0 ), vertexAt( 2 ), vertexAt( 1 ) ) );
472  alt.append( QgsGeometryUtils::perpendicularSegment( vertexAt( 1 ), vertexAt( 0 ), vertexAt( 2 ) ) );
473  alt.append( QgsGeometryUtils::perpendicularSegment( vertexAt( 2 ), vertexAt( 0 ), vertexAt( 1 ) ) );
474 
475  return alt;
476 }
477 
478 QVector<QgsLineString> QgsTriangle::medians() const
479 {
480  QVector<QgsLineString> med;
481  if ( isEmpty() )
482  return med;
483 
484  QgsLineString med1;
485  QgsLineString med2;
486  QgsLineString med3;
490  med.append( med1 );
491  med.append( med2 );
492  med.append( med3 );
493 
494  return med;
495 }
496 
497 QVector<QgsLineString> QgsTriangle::bisectors( double lengthTolerance ) const
498 {
499  QVector<QgsLineString> bis;
500  if ( isEmpty() )
501  return bis;
502 
503  QgsLineString bis1;
504  QgsLineString bis2;
505  QgsLineString bis3;
506  const QgsPoint incenter = inscribedCenter();
507  QgsPoint out;
508  bool intersection = false;
509 
510  QgsGeometryUtils::segmentIntersection( vertexAt( 0 ), incenter, vertexAt( 1 ), vertexAt( 2 ), out, intersection, lengthTolerance );
511  bis1.setPoints( QgsPointSequence() << vertexAt( 0 ) << out );
512 
513  QgsGeometryUtils::segmentIntersection( vertexAt( 1 ), incenter, vertexAt( 0 ), vertexAt( 2 ), out, intersection, lengthTolerance );
514  bis2.setPoints( QgsPointSequence() << vertexAt( 1 ) << out );
515 
516  QgsGeometryUtils::segmentIntersection( vertexAt( 2 ), incenter, vertexAt( 0 ), vertexAt( 1 ), out, intersection, lengthTolerance );
517  bis3.setPoints( QgsPointSequence() << vertexAt( 2 ) << out );
518 
519  bis.append( bis1 );
520  bis.append( bis2 );
521  bis.append( bis3 );
522 
523  return bis;
524 }
525 
527 {
528  if ( isEmpty() )
529  return QgsTriangle();
530  QgsPoint p1, p2, p3;
531  p1 = QgsGeometryUtils::midpoint( vertexAt( 0 ), vertexAt( 1 ) );
532  p2 = QgsGeometryUtils::midpoint( vertexAt( 1 ), vertexAt( 2 ) );
533  p3 = QgsGeometryUtils::midpoint( vertexAt( 2 ), vertexAt( 0 ) );
534  return QgsTriangle( p1, p2, p3 );
535 }
536 
537 QgsPoint QgsTriangle::orthocenter( double lengthTolerance ) const
538 {
539  if ( isEmpty() )
540  return QgsPoint();
541  const QVector<QgsLineString> alt = altitudes();
542  QgsPoint ortho;
543  bool intersection;
544  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 );
545 
546  return ortho;
547 }
548 
550 {
551  if ( isEmpty() )
552  return QgsPoint();
553  double r, x, y;
554  QgsGeometryUtils::circleCenterRadius( vertexAt( 0 ), vertexAt( 1 ), vertexAt( 2 ), r, x, y );
555  return QgsPoint( x, y );
556 }
557 
559 {
560  if ( isEmpty() )
561  return 0.0;
562  double r, x, y;
563  QgsGeometryUtils::circleCenterRadius( vertexAt( 0 ), vertexAt( 1 ), vertexAt( 2 ), r, x, y );
564  return r;
565 }
566 
568 {
569  if ( isEmpty() )
570  return QgsCircle();
572 }
573 
575 {
576  if ( isEmpty() )
577  return QgsPoint();
578 
579  const QVector<double> l = lengths();
580  const double x = ( l.at( 0 ) * vertexAt( 2 ).x() +
581  l.at( 1 ) * vertexAt( 0 ).x() +
582  l.at( 2 ) * vertexAt( 1 ).x() ) / perimeter();
583  const double y = ( l.at( 0 ) * vertexAt( 2 ).y() +
584  l.at( 1 ) * vertexAt( 0 ).y() +
585  l.at( 2 ) * vertexAt( 1 ).y() ) / perimeter();
586 
587  QgsPoint center( x, y );
588 
589  QgsPointSequence points;
590  points << vertexAt( 0 ) << vertexAt( 1 ) << vertexAt( 2 );
592 
593  return center;
594 }
595 
597 {
598  if ( isEmpty() )
599  return 0.0;
600  return ( 2.0 * area() / perimeter() );
601 }
602 
604 {
605  if ( isEmpty() )
606  return QgsCircle();
608 }
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:138
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:174
virtual bool isClosed() const SIP_HOLDGIL
Returns true if the curve is closed.
Definition: qgscurve.cpp:52
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 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 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.
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
bool isClosed() const override SIP_HOLDGIL
Returns true if the curve is closed.
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:59
double y
Definition: qgspointxy.h:63
Q_GADGET double x
Definition: qgspointxy.h:62
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:49
Q_GADGET double x
Definition: qgspoint.h:52
double z
Definition: qgspoint.h:54
double m
Definition: qgspoint.h:55
double y
Definition: qgspoint.h:53
Polygon geometry type.
Definition: qgspolygon.h: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:1108
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.