QGIS API Documentation  3.22.4-Białowieża (ce8e65e95e)
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 ) ) ); // c = |AB|
377  lengths.append( vertexAt( 1 ).distance( vertexAt( 2 ) ) ); // a = |BC|
378  lengths.append( vertexAt( 0 ).distance( vertexAt( 2 ) ) ); // b = |AC|
379 
380  return lengths;
381 }
382 
383 QVector<double> QgsTriangle::angles() const
384 {
385  QVector<double> angles;
386  if ( isEmpty() )
387  return angles;
388 
389  QVector<double> l = lengths();
390 
391  const double a = l[1];
392  const double b = l[2];
393  const double c = l[0];
394 
395  const double a2 = a * a;
396  const double b2 = b * b;
397  const double c2 = c * c;
398 
399  const double alpha = acos( ( b2 + c2 - a2 ) / ( 2 * b * c ) );
400  const double beta = acos( ( a2 + c2 - b2 ) / ( 2 * a * c ) );
401  const double gamma = M_PI - alpha - beta; // acos((a2 + b2 - c2)/(2*a*b)); but ensure that alpha+beta+gamma = 180.0
402 
403  angles.append( alpha );
404  angles.append( beta );
405  angles.append( gamma );
406 
407  return angles;
408 }
409 
411 {
412  if ( isEmpty() )
413  return true;
414 
415  const QgsPoint p1( vertexAt( 0 ) );
416  const QgsPoint p2( vertexAt( 1 ) );
417  const QgsPoint p3( vertexAt( 2 ) );
418  return ( ( ( p1 == p2 ) || ( p1 == p3 ) || ( p2 == p3 ) ) || QgsGeometryUtils::leftOfLine( p1.x(), p1.y(), p2.x(), p2.y(), p3.x(), p3.y() ) == 0 );
419 }
420 
421 bool QgsTriangle::isIsocele( double lengthTolerance ) const
422 {
423  if ( isEmpty() )
424  return false;
425  const QVector<double> sides = lengths();
426  const bool ab_bc = qgsDoubleNear( sides.at( 0 ), sides.at( 1 ), lengthTolerance );
427  const bool bc_ca = qgsDoubleNear( sides.at( 1 ), sides.at( 2 ), lengthTolerance );
428  const bool ca_ab = qgsDoubleNear( sides.at( 2 ), sides.at( 0 ), lengthTolerance );
429 
430  return ( ab_bc || bc_ca || ca_ab );
431 }
432 
433 bool QgsTriangle::isEquilateral( double lengthTolerance ) const
434 {
435  if ( isEmpty() )
436  return false;
437  const QVector<double> sides = lengths();
438  const bool ab_bc = qgsDoubleNear( sides.at( 0 ), sides.at( 1 ), lengthTolerance );
439  const bool bc_ca = qgsDoubleNear( sides.at( 1 ), sides.at( 2 ), lengthTolerance );
440  const bool ca_ab = qgsDoubleNear( sides.at( 2 ), sides.at( 0 ), lengthTolerance );
441 
442  return ( ab_bc && bc_ca && ca_ab );
443 }
444 
445 bool QgsTriangle::isRight( double angleTolerance ) const
446 {
447  if ( isEmpty() )
448  return false;
449  QVector<double> a = angles();
450  QVector<double>::iterator ita = a.begin();
451  while ( ita != a.end() )
452  {
453  if ( qgsDoubleNear( *ita, M_PI_2, angleTolerance ) )
454  return true;
455  ++ita;
456  }
457  return false;
458 }
459 
460 bool QgsTriangle::isScalene( double lengthTolerance ) const
461 {
462  if ( isEmpty() )
463  return false;
464  return !isIsocele( lengthTolerance );
465 }
466 
467 QVector<QgsLineString> QgsTriangle::altitudes() const
468 {
469  QVector<QgsLineString> alt;
470  if ( isEmpty() )
471  return alt;
472 
473  alt.append( QgsGeometryUtils::perpendicularSegment( vertexAt( 0 ), vertexAt( 2 ), vertexAt( 1 ) ) );
474  alt.append( QgsGeometryUtils::perpendicularSegment( vertexAt( 1 ), vertexAt( 0 ), vertexAt( 2 ) ) );
475  alt.append( QgsGeometryUtils::perpendicularSegment( vertexAt( 2 ), vertexAt( 0 ), vertexAt( 1 ) ) );
476 
477  return alt;
478 }
479 
480 QVector<QgsLineString> QgsTriangle::medians() const
481 {
482  QVector<QgsLineString> med;
483  if ( isEmpty() )
484  return med;
485 
486  QgsLineString med1;
487  QgsLineString med2;
488  QgsLineString med3;
492  med.append( med1 );
493  med.append( med2 );
494  med.append( med3 );
495 
496  return med;
497 }
498 
499 QVector<QgsLineString> QgsTriangle::bisectors( double lengthTolerance ) const
500 {
501  QVector<QgsLineString> bis;
502  if ( isEmpty() )
503  return bis;
504 
505  QgsLineString bis1;
506  QgsLineString bis2;
507  QgsLineString bis3;
508  const QgsPoint incenter = inscribedCenter();
509  QgsPoint out;
510  bool intersection = false;
511 
512  QgsGeometryUtils::segmentIntersection( vertexAt( 0 ), incenter, vertexAt( 1 ), vertexAt( 2 ), out, intersection, lengthTolerance );
513  bis1.setPoints( QgsPointSequence() << vertexAt( 0 ) << out );
514 
515  QgsGeometryUtils::segmentIntersection( vertexAt( 1 ), incenter, vertexAt( 0 ), vertexAt( 2 ), out, intersection, lengthTolerance );
516  bis2.setPoints( QgsPointSequence() << vertexAt( 1 ) << out );
517 
518  QgsGeometryUtils::segmentIntersection( vertexAt( 2 ), incenter, vertexAt( 0 ), vertexAt( 1 ), out, intersection, lengthTolerance );
519  bis3.setPoints( QgsPointSequence() << vertexAt( 2 ) << out );
520 
521  bis.append( bis1 );
522  bis.append( bis2 );
523  bis.append( bis3 );
524 
525  return bis;
526 }
527 
529 {
530  if ( isEmpty() )
531  return QgsTriangle();
532  QgsPoint p1, p2, p3;
533  p1 = QgsGeometryUtils::midpoint( vertexAt( 0 ), vertexAt( 1 ) );
534  p2 = QgsGeometryUtils::midpoint( vertexAt( 1 ), vertexAt( 2 ) );
535  p3 = QgsGeometryUtils::midpoint( vertexAt( 2 ), vertexAt( 0 ) );
536  return QgsTriangle( p1, p2, p3 );
537 }
538 
539 QgsPoint QgsTriangle::orthocenter( double lengthTolerance ) const
540 {
541  if ( isEmpty() )
542  return QgsPoint();
543  const QVector<QgsLineString> alt = altitudes();
544  QgsPoint ortho;
545  bool intersection;
546  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 );
547 
548  return ortho;
549 }
550 
552 {
553  if ( isEmpty() )
554  return QgsPoint();
555  double r, x, y;
556  QgsGeometryUtils::circleCenterRadius( vertexAt( 0 ), vertexAt( 1 ), vertexAt( 2 ), r, x, y );
557  return QgsPoint( x, y );
558 }
559 
561 {
562  if ( isEmpty() )
563  return 0.0;
564  double r, x, y;
565  QgsGeometryUtils::circleCenterRadius( vertexAt( 0 ), vertexAt( 1 ), vertexAt( 2 ), r, x, y );
566  return r;
567 }
568 
570 {
571  if ( isEmpty() )
572  return QgsCircle();
574 }
575 
577 {
578  if ( isEmpty() )
579  return QgsPoint();
580 
581  const QVector<double> l = lengths();
582  const double x = ( l.at( 0 ) * vertexAt( 2 ).x() +
583  l.at( 1 ) * vertexAt( 0 ).x() +
584  l.at( 2 ) * vertexAt( 1 ).x() ) / perimeter();
585  const double y = ( l.at( 0 ) * vertexAt( 2 ).y() +
586  l.at( 1 ) * vertexAt( 0 ).y() +
587  l.at( 2 ) * vertexAt( 1 ).y() ) / perimeter();
588 
589  QgsPoint center( x, y );
590 
591  QgsPointSequence points;
592  points << vertexAt( 0 ) << vertexAt( 1 ) << vertexAt( 2 );
594 
595  return center;
596 }
597 
599 {
600  if ( isEmpty() )
601  return 0.0;
602  return ( 2.0 * area() / perimeter() );
603 }
604 
606 {
607  if ( isEmpty() )
608  return QgsCircle();
610 }
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:175
virtual bool isClosed() const SIP_HOLDGIL
Returns true if the curve is closed.
Definition: qgscurve.cpp:53
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 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:968
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:732
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:1246
QVector< QgsPoint > QgsPointSequence
int precision
Utility class for identifying a unique vertex within a geometry.
Definition: qgsvertexid.h:31
int vertex
Vertex number.
Definition: qgsvertexid.h:95
int part
Part number.
Definition: qgsvertexid.h:89
int ring
Ring number.
Definition: qgsvertexid.h:92