Branch data Line data Source code
1 : : /***************************************************************************
2 : : qgstriangle.h
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 : : #ifndef QGSTRIANGLE_H
19 : : #define QGSTRIANGLE_H
20 : :
21 : : #include "qgis_core.h"
22 : : #include "qgis_sip.h"
23 : : #include "qgspolygon.h"
24 : : #include "qgscircle.h"
25 : : #include "qgslinestring.h"
26 : :
27 : : /**
28 : : * \ingroup core
29 : : * \class QgsTriangle
30 : : * \brief Triangle geometry type.
31 : : * \since QGIS 3.0
32 : : */
33 : 531 : class CORE_EXPORT QgsTriangle : public QgsPolygon
34 : : {
35 : : public:
36 : :
37 : : /**
38 : : * Constructor for an empty triangle geometry.
39 : : */
40 : : QgsTriangle() SIP_HOLDGIL;
41 : :
42 : : /**
43 : : * Construct a QgsTriangle from three QgsPoint.
44 : : * \param p1 first point
45 : : * \param p2 second point
46 : : * \param p3 third point
47 : : */
48 : : QgsTriangle( const QgsPoint &p1, const QgsPoint &p2, const QgsPoint &p3 ) SIP_HOLDGIL;
49 : :
50 : : /**
51 : : * Construct a QgsTriangle from three QgsPointXY.
52 : : * \param p1 first point
53 : : * \param p2 second point
54 : : * \param p3 third point
55 : : */
56 : : explicit QgsTriangle( const QgsPointXY &p1, const QgsPointXY &p2, const QgsPointXY &p3 ) SIP_HOLDGIL;
57 : :
58 : : /**
59 : : * Construct a QgsTriangle from three QPointF.
60 : : * \param p1 first point
61 : : * \param p2 second point
62 : : * \param p3 third point
63 : : */
64 : : explicit QgsTriangle( QPointF p1, QPointF p2, QPointF p3 ) SIP_HOLDGIL;
65 : :
66 : : bool operator==( const QgsTriangle &other ) const SIP_HOLDGIL;
67 : : bool operator!=( const QgsTriangle &other ) const SIP_HOLDGIL;
68 : :
69 : : QString geometryType() const override SIP_HOLDGIL;
70 : : QgsTriangle *clone() const override SIP_FACTORY;
71 : : void clear() override;
72 : :
73 : : bool fromWkb( QgsConstWkbPtr &wkbPtr ) override;
74 : :
75 : : bool fromWkt( const QString &wkt ) override;
76 : :
77 : : // inherited: QString asWkt( int precision = 17 ) const;
78 : : // inherited (as a polygon): QDomElement asGML2( QDomDocument &doc, int precision = 17, const QString &ns = "gml" ) const;
79 : : QDomElement asGml3( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override;
80 : :
81 : : QgsPolygon *surfaceToPolygon() const override SIP_FACTORY;
82 : :
83 : : QgsCurvePolygon *toCurveType() const override SIP_FACTORY;
84 : :
85 : : //! Inherited method not used. You cannot add an interior ring into a triangle.
86 : : void addInteriorRing( QgsCurve *ring SIP_TRANSFER ) override;
87 : :
88 : : /**
89 : : * Inherited method not used. You cannot add an interior ring into a triangle.
90 : : * \note not available in Python bindings
91 : : */
92 : : void setInteriorRings( const QVector< QgsCurve *> &rings ) = delete;
93 : : //! Inherited method not used. You cannot delete or insert a vertex directly. Returns always FALSE.
94 : : bool deleteVertex( QgsVertexId position ) override;
95 : : //! Inherited method not used. You cannot delete or insert a vertex directly. Returns always FALSE.
96 : : bool insertVertex( QgsVertexId position, const QgsPoint &vertex ) override;
97 : : bool moveVertex( QgsVertexId vId, const QgsPoint &newPos ) override;
98 : :
99 : : void setExteriorRing( QgsCurve *ring SIP_TRANSFER ) override;
100 : :
101 : : QgsCurve *boundary() const override SIP_FACTORY;
102 : :
103 : : // inherited: double pointDistanceToBoundary( double x, double y ) const;
104 : :
105 : : /**
106 : : * Returns coordinates of a vertex.
107 : : * \param atVertex index of the vertex
108 : : * \returns Coordinates of the vertex or empty QgsPoint on error (\a atVertex < 0 or > 3).
109 : : */
110 : : QgsPoint vertexAt( int atVertex ) const SIP_HOLDGIL;
111 : :
112 : : /**
113 : : * Returns the three lengths of the triangle.
114 : : * \returns Lengths of triangle ABC where [AB] is at 0, [BC] is at 1, [CA] is at 2.
115 : : * An empty list is returned for empty triangle.
116 : : *
117 : : * ### Example
118 : : *
119 : : * \code{.py}
120 : : * tri = QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 0, 5 ), QgsPoint( 5, 5 ) )
121 : : * tri.lengths()
122 : : * # [5.0, 5.0, 7.0710678118654755]
123 : : * QgsTriangle().lengths()
124 : : * # []
125 : : * \endcode
126 : : */
127 : : QVector<double> lengths() const SIP_HOLDGIL;
128 : :
129 : : /**
130 : : * Returns the three angles of the triangle.
131 : : * \returns Angles in radians of triangle ABC where angle BAC is at 0, angle ABC is at 1, angle BCA is at 2.
132 : : * An empty list is returned for empty triangle.
133 : : *
134 : : * ### Example
135 : : *
136 : : * \code{.py}
137 : : * tri = QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 0, 5 ), QgsPoint( 5, 5 ) )
138 : : * [math.degrees(i) for i in tri.angles()]
139 : : * # [45.0, 90.0, 45.0]
140 : : * QgsTriangle().angles()
141 : : * # []
142 : : * \endcode
143 : : */
144 : : QVector<double> angles() const SIP_HOLDGIL;
145 : :
146 : : /**
147 : : * Convenient method checking if the geometry is degenerate (have duplicate or colinear point(s)).
148 : : * \returns TRUE if the triangle is degenerate or empty, otherwise FALSE.
149 : : *
150 : : * ### Example
151 : : *
152 : : * \code{.py}
153 : : * tri = QgsTriangle()
154 : : * tri.isDegenerate()
155 : : * # True
156 : : * tri = QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 0, 5 ), QgsPoint( 5, 5 ) )
157 : : * tri.isDegenerate()
158 : : * # False
159 : : * tri = QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 5, 5 ), QgsPoint( 10, 10 ) )
160 : : * tri.isDegenerate()
161 : : * # True
162 : : * tri = QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 0, 0 ), QgsPoint( 5, 5 ) )
163 : : * tri.isDegenerate()
164 : : * # True
165 : : * \endcode
166 : : */
167 : : bool isDegenerate() SIP_HOLDGIL;
168 : :
169 : : /**
170 : : * Is the triangle isocele (two sides with the same length)?
171 : : * \param lengthTolerance The tolerance to use
172 : : * \returns TRUE or FALSE. Always FALSE for empty triangle.
173 : : *
174 : : * ### Example
175 : : *
176 : : * \code{.py}
177 : : * tri = QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 0, 5 ), QgsPoint( 5, 5 ) )
178 : : * tri.lengths()
179 : : * # [5.0, 5.0, 7.0710678118654755]
180 : : * tri.isIsocele()
181 : : * # True
182 : : * # length of [AB] == length of [BC]
183 : : * QgsTriangle().isIsocele()
184 : : * # False
185 : : * \endcode
186 : : */
187 : : bool isIsocele( double lengthTolerance = 0.0001 ) const SIP_HOLDGIL;
188 : :
189 : : /**
190 : : * Is the triangle equilateral (three sides with the same length)?
191 : : * \param lengthTolerance The tolerance to use
192 : : * \returns TRUE or FALSE. Always FALSE for empty triangle.
193 : : *
194 : : * ### Example
195 : : *
196 : : * \code{.py}
197 : : * tri = QgsTriangle( QgsPoint( 10, 10 ), QgsPoint( 16, 10 ), QgsPoint( 13, 15.1962 ) )
198 : : * tri.lengths()
199 : : * # [6.0, 6.0000412031918575, 6.0000412031918575]
200 : : * tri.isEquilateral()
201 : : * # True
202 : : * # All lengths are close to 6.0
203 : : * QgsTriangle().isEquilateral()
204 : : * # False
205 : : * \endcode
206 : : */
207 : : bool isEquilateral( double lengthTolerance = 0.0001 ) const SIP_HOLDGIL;
208 : :
209 : : /**
210 : : * Is the triangle right-angled?
211 : : * \param angleTolerance The tolerance to use
212 : : * \returns TRUE or FALSE. Always FALSE for empty triangle.
213 : : *
214 : : * ### Example
215 : : *
216 : : * \code{.py}
217 : : * tri = QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 0, 5 ), QgsPoint( 5, 5 ) )
218 : : * [math.degrees(i) for i in tri.angles()]
219 : : * # [45.0, 90.0, 45.0]
220 : : * tri.isRight()
221 : : * # True
222 : : * # angle of ABC == 90
223 : : * QgsTriangle().isRight()
224 : : * # False
225 : : * \endcode
226 : : */
227 : : bool isRight( double angleTolerance = 0.0001 ) const SIP_HOLDGIL;
228 : :
229 : : /**
230 : : * Is the triangle scalene (all sides have different lengths)?
231 : : * \param lengthTolerance The tolerance to use
232 : : * \returns TRUE or FALSE. Always FALSE for empty triangle.
233 : : *
234 : : * ### Example
235 : : *
236 : : * \code{.py}
237 : : * tri = QgsTriangle( QgsPoint( 7.2825, 4.2368 ), QgsPoint( 13.0058, 3.3218 ), QgsPoint( 9.2145, 6.5242 ) )
238 : : * tri.lengths()
239 : : * # [5.795980321740233, 4.962793714229921, 2.994131386562721]
240 : : * tri.isScalene()
241 : : * # True
242 : : * # All lengths are different
243 : : * QgsTriangle().isScalene()
244 : : * # False
245 : : * \endcode
246 : : */
247 : : bool isScalene( double lengthTolerance = 0.0001 ) const SIP_HOLDGIL;
248 : :
249 : : /**
250 : : * An altitude is a segment (defined by a QgsLineString) from a vertex to the opposite side (or, if necessary, to the extension of the opposite side).
251 : : * \returns Three altitudes from this triangle.
252 : : * An empty list is returned for empty triangle.
253 : : *
254 : : * ### Example
255 : : *
256 : : * \code{.py}
257 : : * tri = QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 0, 5 ), QgsPoint( 5, 5 ) )
258 : : * [alt.asWkt() for alt in tri.altitudes()]
259 : : * # ['LineString (0 0, 0 5)', 'LineString (0 5, 2.5 2.5)', 'LineString (5 5, 0 5)']
260 : : * QgsTriangle().altitudes()
261 : : * # []
262 : : * \endcode
263 : : */
264 : : QVector<QgsLineString> altitudes() const SIP_HOLDGIL;
265 : :
266 : : /**
267 : : * A median is a segment (defined by a QgsLineString) from a vertex to the midpoint of the opposite side.
268 : : * \returns Three medians from this triangle.
269 : : * An empty list is returned for empty triangle.
270 : : *
271 : : * ### Example
272 : : *
273 : : * \code{.py}
274 : : * tri = QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 0, 5 ), QgsPoint( 5, 5 ) )
275 : : * [med.asWkt() for med in tri.medians()]
276 : : * # ['LineString (0 0, 2.5 5)', 'LineString (0 5, 2.5 2.5)', 'LineString (5 5, 0 2.5)']
277 : : * QgsTriangle().medians()
278 : : * # []
279 : : * \endcode
280 : : */
281 : : QVector<QgsLineString> medians() const SIP_HOLDGIL;
282 : :
283 : : /**
284 : : * The segment (defined by a QgsLineString) returned bisect the angle of a vertex to the opposite side.
285 : : * \param lengthTolerance The tolerance to use.
286 : : * \returns Three angle bisector from this triangle.
287 : : * An empty list is returned for empty triangle.
288 : : *
289 : : * ### Example
290 : : *
291 : : * \code{.py}
292 : : * tri = QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 0, 5 ), QgsPoint( 5, 5 ) )
293 : : * [bis.asWkt() for bis in tri.bisectors()]
294 : : * # ['LineString (0 0, 2.07106781186547462 5)', 'LineString (0 5, 2.5 2.5)', 'LineString (5 5, 0 2.92893218813452538)']
295 : : * QgsTriangle().bisectors()
296 : : * # []
297 : : * \endcode
298 : : */
299 : : QVector<QgsLineString> bisectors( double lengthTolerance = 0.0001 ) const SIP_HOLDGIL;
300 : :
301 : : /**
302 : : * Medial (or midpoint) triangle of a triangle ABC is the triangle with vertices at the midpoints of the triangle's sides.
303 : : * \returns The medial from this triangle.
304 : : * An empty triangle is returned for empty triangle.
305 : : *
306 : : * ### Example
307 : : *
308 : : * \code{.py}
309 : : * tri = QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 0, 5 ), QgsPoint( 5, 5 ) )
310 : : * tri.medial().asWkt()
311 : : * # 'Triangle ((0 2.5, 2.5 5, 2.5 2.5, 0 2.5))'
312 : : * QgsTriangle().medial().asWkt()
313 : : * # 'Triangle ( )'
314 : : * \endcode
315 : : */
316 : : QgsTriangle medial() const SIP_HOLDGIL;
317 : :
318 : : /**
319 : : * An orthocenter is the point of intersection of the altitudes of a triangle.
320 : : * \param lengthTolerance The tolerance to use
321 : : * \returns The orthocenter of the triangle.
322 : : * An empty point is returned for empty triangle.
323 : : *
324 : : * ### Example
325 : : *
326 : : * \code{.py}
327 : : * tri = QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 0, 5 ), QgsPoint( 5, 5 ) )
328 : : * tri.orthocenter().asWkt()
329 : : * # 'Point (0 5)'
330 : : * QgsTriangle().orthocenter().asWkt()
331 : : * # 'Point (0 0)'
332 : : * \endcode
333 : : */
334 : : QgsPoint orthocenter( double lengthTolerance = 0.0001 ) const SIP_HOLDGIL;
335 : :
336 : : /**
337 : : * Center of the circumscribed circle of the triangle.
338 : : * \returns The center of the circumscribed circle of the triangle.
339 : : * An empty point is returned for empty triangle.
340 : : *
341 : : * ### Example
342 : : *
343 : : * \code{.py}
344 : : * tri = QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 0, 5 ), QgsPoint( 5, 5 ) )
345 : : * tri.circumscribedCenter().asWkt()
346 : : * # 'Point (2.5 2.5)'
347 : : * QgsTriangle().circumscribedCenter().asWkt()
348 : : * # 'Point (0 0)'
349 : : * \endcode
350 : : */
351 : : QgsPoint circumscribedCenter() const SIP_HOLDGIL;
352 : :
353 : : /**
354 : : * Radius of the circumscribed circle of the triangle.
355 : : * \returns The radius of the circumscribed circle of the triangle.
356 : : * 0.0 is returned for empty triangle.
357 : : *
358 : : * ### Example
359 : : *
360 : : * \code{.py}
361 : : * tri = QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 0, 5 ), QgsPoint( 5, 5 ) )
362 : : * tri.circumscribedRadius()
363 : : * # 3.5355339059327378
364 : : * QgsTriangle().circumscribedRadius()
365 : : * # 0.0
366 : : * \endcode
367 : : */
368 : : double circumscribedRadius() const SIP_HOLDGIL;
369 : :
370 : : /**
371 : : * Circumscribed circle of the triangle.
372 : : * \returns The circumbscribed of the triangle with a QgsCircle.
373 : : * An empty circle is returned for empty triangle.
374 : : *
375 : : * ### Example
376 : : *
377 : : * \code{.py}
378 : : * tri = QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 0, 5 ), QgsPoint( 5, 5 ) )
379 : : * tri.circumscribedCircle()
380 : : * # QgsCircle(Point (2.5 2.5), 3.5355339059327378, 0)
381 : : * QgsTriangle().circumscribedCircle()
382 : : * # QgsCircle()
383 : : * \endcode
384 : : */
385 : : QgsCircle circumscribedCircle() const SIP_HOLDGIL;
386 : :
387 : : /**
388 : : * Center of the inscribed circle of the triangle. Z dimension is
389 : : * supported and is retrieved from the first 3D point amongst vertices.
390 : : * \returns The center of the inscribed circle of the triangle.
391 : : * An empty point is returned for empty triangle.
392 : : *
393 : : * ### Example
394 : : *
395 : : * \code{.py}
396 : : * tri = QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 0, 5 ), QgsPoint( 5, 5 ) )
397 : : * tri.inscribedCenter().asWkt()
398 : : * # 'Point (1.46446609406726225 3.53553390593273775)'
399 : : * QgsTriangle().inscribedCenter().asWkt()
400 : : * # 'Point (0 0)'
401 : : * \endcode
402 : : */
403 : : QgsPoint inscribedCenter() const SIP_HOLDGIL;
404 : :
405 : : /**
406 : : * Radius of the inscribed circle of the triangle.
407 : : * \returns The radius of the inscribed circle of the triangle.
408 : : * 0.0 is returned for empty triangle.
409 : : *
410 : : * ### Example
411 : : *
412 : : * \code{.py}
413 : : * tri = QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 0, 5 ), QgsPoint( 5, 5 ) )
414 : : * tri.inscribedRadius()
415 : : * # 1.4644660940672622
416 : : * QgsTriangle().inscribedRadius()
417 : : * # 0.0
418 : : * \endcode
419 : : */
420 : : double inscribedRadius() const SIP_HOLDGIL;
421 : :
422 : : /**
423 : : * Inscribed circle of the triangle.
424 : : * \returns The inscribed of the triangle with a QgsCircle.
425 : : * An empty circle is returned for empty triangle.
426 : : *
427 : : * ### Example
428 : : *
429 : : * \code{.py}
430 : : * tri = QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 0, 5 ), QgsPoint( 5, 5 ) )
431 : : * tri.inscribedCircle()
432 : : * # QgsCircle(Point (1.46446609406726225 3.53553390593273775), 1.4644660940672622, 0)
433 : : * QgsTriangle().inscribedCircle()
434 : : * # QgsCircle()
435 : : * \endcode
436 : : */
437 : : QgsCircle inscribedCircle() const SIP_HOLDGIL;
438 : :
439 : : #ifndef SIP_RUN
440 : :
441 : : /**
442 : : * Cast the \a geom to a QgsTriangle.
443 : : * Should be used by qgsgeometry_cast<QgsTriangle *>( geometry ).
444 : : *
445 : : * \note Not available in Python. Objects will be automatically be converted to the appropriate target type.
446 : : * \since QGIS 3.0
447 : : */
448 : : inline static const QgsTriangle *cast( const QgsAbstractGeometry *geom )
449 : : {
450 : : if ( geom && QgsWkbTypes::flatType( geom->wkbType() ) == QgsWkbTypes::Triangle )
451 : : return static_cast<const QgsTriangle *>( geom );
452 : : return nullptr;
453 : : }
454 : : #endif
455 : :
456 : : QgsTriangle *createEmptyWithSameType() const override SIP_FACTORY;
457 : :
458 : :
459 : : };
460 : : #endif // QGSTRIANGLE_H
|