QGIS API Documentation  3.10.0-A Coruña (6c816b4204)
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 
163  clear();
164 
165  QPair<QgsWkbTypes::Type, QString> parts = QgsGeometryUtils::wktReadBlock( wkt );
166 
168  return false;
169 
170  mWkbType = parts.first;
171 
172  if ( parts.second.compare( QLatin1String( "EMPTY" ), Qt::CaseInsensitive ) == 0 )
173  return true;
174 
175  QString defaultChildWkbType = QStringLiteral( "LineString%1%2" ).arg( is3D() ? QStringLiteral( "Z" ) : QString(), isMeasure() ? QStringLiteral( "M" ) : QString() );
176 
177  const QStringList blocks = QgsGeometryUtils::wktGetChildBlocks( parts.second, defaultChildWkbType );
178  for ( const QString &childWkt : blocks )
179  {
180  QPair<QgsWkbTypes::Type, QString> childParts = QgsGeometryUtils::wktReadBlock( childWkt );
181 
182  QgsWkbTypes::Type flatCurveType = QgsWkbTypes::flatType( childParts.first );
183  if ( flatCurveType == QgsWkbTypes::LineString )
184  mInteriorRings.append( new QgsLineString() );
185  else
186  {
187  clear();
188  return false;
189  }
190  if ( !mInteriorRings.back()->fromWkt( childWkt ) )
191  {
192  clear();
193  return false;
194  }
195  }
196 
197  if ( mInteriorRings.isEmpty() )
198  {
199  clear();
200  return false;
201  }
202  mExteriorRing.reset( mInteriorRings.takeFirst() );
203 
204  //scan through rings and check if dimensionality of rings is different to CurvePolygon.
205  //if so, update the type dimensionality of the CurvePolygon to match
206  bool hasZ = false;
207  bool hasM = false;
208  if ( mExteriorRing )
209  {
210  hasZ = hasZ || mExteriorRing->is3D();
211  hasM = hasM || mExteriorRing->isMeasure();
212  }
213  if ( hasZ )
214  addZValue( 0 );
215  if ( hasM )
216  addMValue( 0 );
217 
218  return true;
219 }
220 
221 QDomElement QgsTriangle::asGml3( QDomDocument &doc, int precision, const QString &ns, const AxisOrder axisOrder ) const
222 {
223 
224  QDomElement elemTriangle = doc.createElementNS( ns, QStringLiteral( "Triangle" ) );
225 
226  if ( isEmpty() )
227  return elemTriangle;
228 
229  QDomElement elemExterior = doc.createElementNS( ns, QStringLiteral( "exterior" ) );
230  QDomElement curveElem = exteriorRing()->asGml3( doc, precision, ns, axisOrder );
231  if ( curveElem.tagName() == QLatin1String( "LineString" ) )
232  {
233  curveElem.setTagName( QStringLiteral( "LinearRing" ) );
234  }
235  elemExterior.appendChild( curveElem );
236  elemTriangle.appendChild( elemExterior );
237 
238  return elemTriangle;
239 }
240 
242 {
243  return toPolygon();
244 }
245 
247 {
248  std::unique_ptr<QgsCurvePolygon> curvePolygon( new QgsCurvePolygon() );
249  curvePolygon->setExteriorRing( mExteriorRing->clone() );
250 
251  return curvePolygon.release();
252 }
253 
255 {
256  delete ring;
257 }
258 
260 {
261  Q_UNUSED( position )
262  return false;
263 }
264 
265 bool QgsTriangle::insertVertex( QgsVertexId position, const QgsPoint &vertex )
266 {
267  Q_UNUSED( position )
268  Q_UNUSED( vertex )
269  return false;
270 }
271 
272 bool QgsTriangle::moveVertex( QgsVertexId vId, const QgsPoint &newPos )
273 {
274  if ( isEmpty() )
275  return false;
276 
277  if ( !mExteriorRing || vId.part != 0 || vId.ring != 0 || vId.vertex < 0 || vId.vertex > 4 )
278  {
279  return false;
280  }
281 
282  if ( vId.vertex == 4 )
283  {
284  vId.vertex = 0;
285  }
286 
287  int n = mExteriorRing->numPoints();
288  bool success = mExteriorRing->moveVertex( vId, newPos );
289  if ( success )
290  {
291  // If first or last vertex is moved, also move the last/first vertex
292  if ( vId.vertex == 0 )
293  mExteriorRing->moveVertex( QgsVertexId( vId.part, vId.ring, n - 1 ), newPos );
294  clearCache();
295  }
296  return success;
297 }
298 
300 {
301  if ( !ring )
302  {
303  return;
304  }
305 
306  if ( ring->hasCurvedSegments() )
307  {
308  //need to segmentize ring as polygon does not support curves
309  QgsCurve *line = ring->segmentize();
310  delete ring;
311  ring = line;
312  }
313 
314  if ( ( ring->numPoints() > 4 ) || ( ring->numPoints() < 3 ) )
315  {
316  delete ring;
317  return;
318  }
319  else if ( ring->numPoints() == 4 )
320  {
321  if ( !ring->isClosed() )
322  {
323  delete ring;
324  return;
325  }
326  }
327  else if ( ring->numPoints() == 3 )
328  {
329  if ( ring->isClosed() )
330  {
331  delete ring;
332  return;
333  }
334  QgsLineString *lineString = static_cast< QgsLineString *>( ring );
335  if ( !lineString->isClosed() )
336  {
337  lineString->close();
338  }
339  ring = lineString;
340  }
341 
342  mExteriorRing.reset( ring );
343 
344  //set proper wkb type
346 
347  clearCache();
348 }
349 
351 {
352  if ( !mExteriorRing )
353  return nullptr;
354 
355  return mExteriorRing->clone();
356 }
357 
358 QgsPoint QgsTriangle::vertexAt( int atVertex ) const
359 {
360  if ( isEmpty() )
361  return QgsPoint();
362 
363  QgsVertexId id( 0, 0, atVertex );
364  return mExteriorRing->vertexAt( id );
365 }
366 
367 QVector<double> QgsTriangle::lengths() const
368 {
369  QVector<double> lengths;
370  if ( isEmpty() )
371  return lengths;
372 
373  lengths.append( vertexAt( 0 ).distance( vertexAt( 1 ) ) );
374  lengths.append( vertexAt( 1 ).distance( vertexAt( 2 ) ) );
375  lengths.append( vertexAt( 2 ).distance( vertexAt( 0 ) ) );
376 
377  return lengths;
378 }
379 
380 QVector<double> QgsTriangle::angles() const
381 {
382  QVector<double> angles;
383  if ( isEmpty() )
384  return angles;
385  double ax, ay, bx, by, cx, cy;
386 
387  ax = vertexAt( 0 ).x();
388  ay = vertexAt( 0 ).y();
389  bx = vertexAt( 1 ).x();
390  by = vertexAt( 1 ).y();
391  cx = vertexAt( 2 ).x();
392  cy = vertexAt( 2 ).y();
393 
394  double a1 = std::fmod( QgsGeometryUtils::angleBetweenThreePoints( cx, cy, ax, ay, bx, by ), M_PI );
395  double a2 = std::fmod( QgsGeometryUtils::angleBetweenThreePoints( ax, ay, bx, by, cx, cy ), M_PI );
396  double a3 = std::fmod( QgsGeometryUtils::angleBetweenThreePoints( bx, by, cx, cy, ax, ay ), M_PI );
397 
398  angles.append( ( a1 > M_PI_2 ? a1 - M_PI_2 : a1 ) );
399  angles.append( ( a2 > M_PI_2 ? a2 - M_PI_2 : a2 ) );
400  angles.append( ( a3 > M_PI_2 ? a3 - M_PI_2 : a3 ) );
401 
402  return angles;
403 }
404 
406 {
407  if ( isEmpty() )
408  return true;
409 
410  QgsPoint p1( vertexAt( 0 ) );
411  QgsPoint p2( vertexAt( 1 ) );
412  QgsPoint p3( vertexAt( 2 ) );
413  return ( ( ( p1 == p2 ) || ( p1 == p3 ) || ( p2 == p3 ) ) || QgsGeometryUtils::leftOfLine( p1.x(), p1.y(), p2.x(), p2.y(), p3.x(), p3.y() ) == 0 );
414 }
415 
416 bool QgsTriangle::isIsocele( double lengthTolerance ) const
417 {
418  if ( isEmpty() )
419  return false;
420  QVector<double> sides = lengths();
421  bool ab_bc = qgsDoubleNear( sides.at( 0 ), sides.at( 1 ), lengthTolerance );
422  bool bc_ca = qgsDoubleNear( sides.at( 1 ), sides.at( 2 ), lengthTolerance );
423  bool ca_ab = qgsDoubleNear( sides.at( 2 ), sides.at( 0 ), lengthTolerance );
424 
425  return ( ab_bc || bc_ca || ca_ab );
426 }
427 
428 bool QgsTriangle::isEquilateral( double lengthTolerance ) const
429 {
430  if ( isEmpty() )
431  return false;
432  QVector<double> sides = lengths();
433  bool ab_bc = qgsDoubleNear( sides.at( 0 ), sides.at( 1 ), lengthTolerance );
434  bool bc_ca = qgsDoubleNear( sides.at( 1 ), sides.at( 2 ), lengthTolerance );
435  bool ca_ab = qgsDoubleNear( sides.at( 2 ), sides.at( 0 ), lengthTolerance );
436 
437  return ( ab_bc && bc_ca && ca_ab );
438 }
439 
440 bool QgsTriangle::isRight( double angleTolerance ) const
441 {
442  if ( isEmpty() )
443  return false;
444  QVector<double> a = angles();
445  QVector<double>::iterator ita = a.begin();
446  while ( ita != a.end() )
447  {
448  if ( qgsDoubleNear( *ita, M_PI_2, angleTolerance ) )
449  return true;
450  ita++;
451  }
452  return false;
453 }
454 
455 bool QgsTriangle::isScalene( double lengthTolerance ) const
456 {
457  if ( isEmpty() )
458  return false;
459  return !isIsocele( lengthTolerance );
460 }
461 
462 QVector<QgsLineString> QgsTriangle::altitudes() const
463 {
464  QVector<QgsLineString> alt;
465  if ( isEmpty() )
466  return alt;
467 
468  alt.append( QgsGeometryUtils::perpendicularSegment( vertexAt( 0 ), vertexAt( 2 ), vertexAt( 1 ) ) );
469  alt.append( QgsGeometryUtils::perpendicularSegment( vertexAt( 1 ), vertexAt( 0 ), vertexAt( 2 ) ) );
470  alt.append( QgsGeometryUtils::perpendicularSegment( vertexAt( 2 ), vertexAt( 0 ), vertexAt( 1 ) ) );
471 
472  return alt;
473 }
474 
475 QVector<QgsLineString> QgsTriangle::medians() const
476 {
477  QVector<QgsLineString> med;
478  if ( isEmpty() )
479  return med;
480 
481  QgsLineString med1;
482  QgsLineString med2;
483  QgsLineString med3;
487  med.append( med1 );
488  med.append( med2 );
489  med.append( med3 );
490 
491  return med;
492 }
493 
494 QVector<QgsLineString> QgsTriangle::bisectors( double lengthTolerance ) const
495 {
496  QVector<QgsLineString> bis;
497  if ( isEmpty() )
498  return bis;
499 
500  QgsLineString bis1;
501  QgsLineString bis2;
502  QgsLineString bis3;
503  QgsPoint incenter = inscribedCenter();
504  QgsPoint out;
505  bool intersection = false;
506 
507  QgsGeometryUtils::segmentIntersection( vertexAt( 0 ), incenter, vertexAt( 1 ), vertexAt( 2 ), out, intersection, lengthTolerance );
508  bis1.setPoints( QgsPointSequence() << vertexAt( 0 ) << out );
509 
510  QgsGeometryUtils::segmentIntersection( vertexAt( 1 ), incenter, vertexAt( 0 ), vertexAt( 2 ), out, intersection, lengthTolerance );
511  bis2.setPoints( QgsPointSequence() << vertexAt( 1 ) << out );
512 
513  QgsGeometryUtils::segmentIntersection( vertexAt( 2 ), incenter, vertexAt( 0 ), vertexAt( 1 ), out, intersection, lengthTolerance );
514  bis3.setPoints( QgsPointSequence() << vertexAt( 2 ) << out );
515 
516  bis.append( bis1 );
517  bis.append( bis2 );
518  bis.append( bis3 );
519 
520  return bis;
521 }
522 
524 {
525  if ( isEmpty() )
526  return QgsTriangle();
527  QgsPoint p1, p2, p3;
528  p1 = QgsGeometryUtils::midpoint( vertexAt( 0 ), vertexAt( 1 ) );
529  p2 = QgsGeometryUtils::midpoint( vertexAt( 1 ), vertexAt( 2 ) );
530  p3 = QgsGeometryUtils::midpoint( vertexAt( 2 ), vertexAt( 0 ) );
531  return QgsTriangle( p1, p2, p3 );
532 }
533 
534 QgsPoint QgsTriangle::orthocenter( double lengthTolerance ) const
535 {
536  if ( isEmpty() )
537  return QgsPoint();
538  QVector<QgsLineString> alt = altitudes();
539  QgsPoint ortho;
540  bool intersection;
541  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 );
542 
543  return ortho;
544 }
545 
547 {
548  if ( isEmpty() )
549  return QgsPoint();
550  double r, x, y;
551  QgsGeometryUtils::circleCenterRadius( vertexAt( 0 ), vertexAt( 1 ), vertexAt( 2 ), r, x, y );
552  return QgsPoint( x, y );
553 }
554 
556 {
557  if ( isEmpty() )
558  return 0.0;
559  double r, x, y;
560  QgsGeometryUtils::circleCenterRadius( vertexAt( 0 ), vertexAt( 1 ), vertexAt( 2 ), r, x, y );
561  return r;
562 }
563 
565 {
566  if ( isEmpty() )
567  return QgsCircle();
569 }
570 
572 {
573  if ( isEmpty() )
574  return QgsPoint();
575 
576  QVector<double> l = lengths();
577  double x = ( l.at( 0 ) * vertexAt( 2 ).x() +
578  l.at( 1 ) * vertexAt( 0 ).x() +
579  l.at( 2 ) * vertexAt( 1 ).x() ) / perimeter();
580  double y = ( l.at( 0 ) * vertexAt( 2 ).y() +
581  l.at( 1 ) * vertexAt( 0 ).y() +
582  l.at( 2 ) * vertexAt( 1 ).y() ) / perimeter();
583 
584  QgsPoint center( x, y );
585 
586  QgsPointSequence points;
587  points << vertexAt( 0 ) << vertexAt( 1 ) << vertexAt( 2 );
588  QgsGeometryUtils::setZValueFromPoints( points, center );
589 
590  return center;
591 }
592 
594 {
595  if ( isEmpty() )
596  return 0.0;
597  return ( 2.0 * area() / perimeter() );
598 }
599 
601 {
602  if ( isEmpty() )
603  return QgsCircle();
605 }
bool isMeasure() const
Returns true if the geometry contains m values.
QgsPolygon * surfaceToPolygon() const override
Gets a polygon representation of this surface.
Circle geometry type.
Definition: qgscircle.h:43
int precision
double y
Definition: qgspoint.h:42
void setPoints(const QgsPointSequence &points)
Resets the line string to match the specified list of points.
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
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.
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.
void clearCache() const override
Clears any cached parameters associated with the geometry, e.g., bounding boxes.
Definition: qgssurface.cpp:43
QgsPoint circumscribedCenter() const
Center of the circumscribed circle of the triangle.
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 (...
QVector< double > angles() const
Returns the three angles of the triangle.
bool operator!=(const QgsTriangle &other) const
Definition: qgstriangle.cpp:86
bool fromWkt(const QString &wkt) override
Sets the geometry from a WKT string.
static double angleBetweenThreePoints(double x1, double y1, double x2, double y2, double x3, double y3)
Calculates the angle between the lines AB and BC, where AB and BC described by points a...
bool deleteVertex(QgsVertexId position) override
Inherited method not used. You cannot delete or insert a vertex directly. Returns always false...
double y
Definition: qgspointxy.h:48
A class to represent a 2D point.
Definition: qgspointxy.h:43
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:280
Curve polygon geometry type.
bool isIsocele(double lengthTolerance=0.0001) const
Is the triangle isocele (two sides with the same length)?
void addInteriorRing(QgsCurve *ring) override
Inherited method not used. You cannot add an interior ring into a triangle.
Triangle geometry type.
Definition: qgstriangle.h:33
double area() const override
Returns the planar, 2-dimensional area of the geometry.
static QStringList wktGetChildBlocks(const QString &wkt, const QString &defaultType=QString())
Parses a WKT string and returns of list of blocks contained in the WKT.
QgsWkbTypes::Type mWkbType
QVector< QgsCurve * > mInteriorRings
QgsTriangle * clone() const override
Clones the geometry by performing a deep copy.
QgsCurve * boundary() const override
Returns the closure of the combinatorial boundary of the geometry (ie the topological boundary of the...
QgsPoint vertexAt(int atVertex) const
Returns coordinates of a vertex.
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:68
double inscribedRadius() const
Radius of the inscribed circle of the triangle.
QgsPoint inscribedCenter() const
Center of the inscribed circle of the triangle.
void clear() override
Clears the geometry, ie reset it to a null geometry.
Definition: qgspolygon.cpp:47
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 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).
QgsGeometryConstPartIterator parts() const
Returns Java-style iterator for traversal of parts of the geometry.
Utility class for identifying a unique vertex within a geometry.
QgsTriangle medial() const
Medial (or midpoint) triangle of a triangle ABC is the triangle with vertices at the midpoints of the...
static QgsPoint midpoint(const QgsPoint &pt1, const QgsPoint &pt2)
Returns a middle point between points pt1 and pt2.
static GeometryType geometryType(Type type)
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
Definition: qgswkbtypes.h:812
void setZMTypeFromSubGeometry(const QgsAbstractGeometry *subggeom, QgsWkbTypes::Type baseGeomType)
Updates the geometry type based on whether sub geometries contain z or m values.
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 addMValue(double mValue=0) override
Adds a measure to the geometry, initialized to a preset value.
double perimeter() const override
Returns the planar, 2-dimensional perimeter of the geometry.
QVector< QgsLineString > altitudes() const
An altitude is a segment (defined by a QgsLineString) from a vertex to the opposite side (or...
void close()
Closes the line string by appending the first point to the end of the line, if it is not already clos...
bool isEquilateral(double lengthTolerance=0.0001) const
Is the triangle equilateral (three sides with the same length)?
Abstract base class for curved geometry type.
Definition: qgscurve.h:35
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...
double circumscribedRadius() const
Radius of the circumscribed 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
Is the triangle scalene (all sides have different lengths)?
bool fromWkb(QgsConstWkbPtr &wkbPtr) override
Sets the geometry from a WKB string.
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:37
void setExteriorRing(QgsCurve *ring) override
Sets the exterior ring of the polygon.
bool moveVertex(QgsVertexId vId, const QgsPoint &newPos) override
Moves a vertex within the geometry.
QVector< QgsLineString > medians() const
A median is a segment (defined by a QgsLineString) from a vertex to the midpoint of the opposite side...
AxisOrder
Axis order for GML generation.
double x
Definition: qgspointxy.h:47
virtual bool isClosed() const
Returns true if the curve is closed.
Definition: qgscurve.cpp:40
QVector< QgsPoint > QgsPointSequence
QgsCurve * segmentize(double tolerance=M_PI_2/90, SegmentationToleranceType toleranceType=MaximumAngle) const override
Returns a geometry without curves.
Definition: qgscurve.cpp:148
bool isDegenerate()
Convenient method checking if the geometry is degenerate (have duplicate or colinear point(s))...
static QgsLineString perpendicularSegment(const QgsPoint &p, const QgsPoint &s1, const QgsPoint &s2)
Create a perpendicular line segment from p to segment [s1, s2].
QgsPoint orthocenter(double lengthTolerance=0.0001) const
An orthocenter is the point of intersection of the altitudes of a triangle.
Line string geometry type, with support for z-dimension and m-values.
Definition: qgslinestring.h:43
void clear() override
Clears the geometry, ie reset it to a null geometry.
bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value.
bool insertVertex(QgsVertexId position, const QgsPoint &vertex) override
Inherited method not used. You cannot delete or insert a vertex directly. Returns always false...
QVector< double > lengths() const
Returns the three lengths of the triangle.
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.
QString geometryType() const override
Returns a unique string representing the geometry type.
Definition: qgstriangle.cpp:91
double z
Definition: qgspoint.h:43
QgsCircle circumscribedCircle() const
Circumscribed circle of the triangle.
Polygon geometry type.
Definition: qgspolygon.h:31
const QgsCurve * exteriorRing() const
Returns the curve polygon&#39;s exterior ring.
bool operator==(const QgsTriangle &other) const
Definition: qgstriangle.cpp:69
std::unique_ptr< QgsCurve > mExteriorRing
static Type flatType(Type type)
Returns the flat type for a WKB type.
Definition: qgswkbtypes.h:576
QgsWkbTypes::Type readHeader() const
readHeader
Definition: qgswkbptr.cpp:54
virtual bool hasCurvedSegments() const
Returns true if the geometry contains curved segments.
bool isEmpty() const override
Returns true if the geometry is empty.
bool isRight(double angleTolerance=0.0001) const
Is the triangle right-angled?
virtual int numPoints() const =0
Returns the number of points in the curve.
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
double m
Definition: qgspoint.h:44
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.
QgsCircle inscribedCircle() const
Inscribed circle of the triangle.
double x
Definition: qgspoint.h:41