QGIS API Documentation 4.0.0-Norrköping (1ddcee3d0e4)
Loading...
Searching...
No Matches
qgsregularpolygon.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsregularpolygon.cpp
3 --------------
4 begin : May 2017
5 copyright : (C) 2017 by Loïc Bartoletti
6 email : lituus at free dot fr
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 "qgsregularpolygon.h"
19
20#include <memory>
21
22#include "qgsgeometryutils.h"
23
24#include <QString>
25
26using namespace Qt::StringLiterals;
27
28QgsRegularPolygon::QgsRegularPolygon( const QgsPoint &center, const double radius, const double azimuth, const unsigned int numSides, const ConstructionOption circle )
29 : mCenter( center )
30{
31 // TODO: inclination
32
33 if ( numSides >= 3 )
34 {
35 mNumberSides = numSides;
36
37 switch ( circle )
38 {
39 case InscribedCircle:
40 {
41 mRadius = std::fabs( radius );
42 mFirstVertex = mCenter.project( mRadius, azimuth );
43 break;
44 }
46 {
47 mRadius = apothemToRadius( std::fabs( radius ), numSides );
48 mFirstVertex = mCenter.project( mRadius, azimuth - centralAngle( numSides ) / 2 );
49 break;
50 }
51 }
52 }
53}
54
55QgsRegularPolygon::QgsRegularPolygon( const QgsPoint &center, const QgsPoint &pt1, const unsigned int numSides, const ConstructionOption circle )
56 : mCenter( center )
57{
58 if ( numSides >= 3 )
59 {
60 mNumberSides = numSides;
61
62 switch ( circle )
63 {
64 case InscribedCircle:
65 {
66 mFirstVertex = pt1;
67 mRadius = center.distance( pt1 );
68 break;
69 }
71 {
72 mRadius = apothemToRadius( center.distance( pt1 ), numSides );
73 const double azimuth = center.azimuth( pt1 );
74 // TODO: inclination
75 mFirstVertex = mCenter.project( mRadius, azimuth - centralAngle( numSides ) / 2 );
76 break;
77 }
78 }
79 }
80}
81
82QgsRegularPolygon::QgsRegularPolygon( const QgsPoint &pt1, const QgsPoint &pt2, const unsigned int numSides )
83{
84 if ( numSides >= 3 )
85 {
86 mNumberSides = numSides;
87
88 const double azimuth = pt1.azimuth( pt2 );
89 const QgsPoint pm = QgsGeometryUtils::midpoint( pt1, pt2 );
90 const double length = pt1.distance( pm );
91
92 const double angle = ( 180 - ( 360 / numSides ) ) / 2.0;
93 const double hypothenuse = length / std::cos( angle * M_PI / 180 );
94 // TODO: inclination
95
96 mCenter = pt1.project( hypothenuse, azimuth + angle );
97 mFirstVertex = pt1;
98 mRadius = std::fabs( hypothenuse );
99 }
100}
101
103{
104 return ( ( mCenter == rp.mCenter ) && ( mFirstVertex == rp.mFirstVertex ) && ( mNumberSides == rp.mNumberSides ) );
105}
106
108{
109 return !operator==( rp );
110}
111
113{
114 return ( ( mNumberSides < 3 ) || ( mCenter.isEmpty() ) || ( mFirstVertex.isEmpty() ) || ( mCenter == mFirstVertex ) );
115}
116
118{
119 const double azimuth = mFirstVertex.isEmpty() ? 0 : mCenter.azimuth( mFirstVertex );
120 // TODO: double inclination = mCenter.inclination(mFirstVertex);
121 mCenter = center;
122 mFirstVertex = center.project( mRadius, azimuth );
123}
124
126{
127 mRadius = std::fabs( radius );
128 const double azimuth = mFirstVertex.isEmpty() ? 0 : mCenter.azimuth( mFirstVertex );
129 // TODO: double inclination = mCenter.inclination(mFirstVertex);
130 mFirstVertex = mCenter.project( mRadius, azimuth );
131}
132
134{
135 const double azimuth = mCenter.azimuth( mFirstVertex );
136 // TODO: double inclination = mCenter.inclination(firstVertex);
137 mFirstVertex = firstVertex;
138 mCenter = mFirstVertex.project( mRadius, azimuth );
139}
140
141void QgsRegularPolygon::setNumberSides( const unsigned int numSides )
142{
143 if ( numSides >= 3 )
144 {
145 mNumberSides = numSides;
146 }
147}
148
150{
152 if ( isEmpty() )
153 {
154 return pts;
155 }
156
157 double azimuth = mCenter.azimuth( mFirstVertex );
158 const double azimuth_add = centralAngle();
159 // TODO: inclination
160
161 unsigned int n = 1;
162 while ( n <= mNumberSides )
163 {
164 pts.push_back( mCenter.project( mRadius, azimuth ) );
165 azimuth += azimuth_add;
166 if ( ( azimuth_add > 0 ) && ( azimuth > 180.0 ) )
167 {
168 azimuth -= 360.0;
169 }
170
171 n++;
172 }
173
174 return pts;
175}
176
178{
179 auto polygon = std::make_unique<QgsPolygon>();
180 if ( isEmpty() )
181 {
182 return polygon.release();
183 }
184
185 polygon->setExteriorRing( toLineString() );
186
187 return polygon.release();
188}
189
191{
192 auto ext = std::make_unique<QgsLineString>();
193 if ( isEmpty() )
194 {
195 return ext.release();
196 }
197
199 pts = points();
200
201 ext->setPoints( pts );
202 ext->addVertex( pts.at( 0 ) ); //close regular polygon
203
204 return ext.release();
205}
206
208{
209 if ( isEmpty() || ( mNumberSides != 3 ) )
210 {
211 return QgsTriangle();
212 }
213
215 pts = points();
216
217 return QgsTriangle( pts.at( 0 ), pts.at( 1 ), pts.at( 2 ) );
218}
219
220QVector<QgsTriangle> QgsRegularPolygon::triangulate() const
221{
222 QVector<QgsTriangle> l_tri;
223 if ( isEmpty() )
224 {
225 return l_tri;
226 }
227
229 pts = points();
230
231 unsigned int n = 0;
232 while ( n < mNumberSides - 1 )
233 {
234 l_tri.append( QgsTriangle( pts.at( n ), pts.at( n + 1 ), mCenter ) );
235 n++;
236 }
237 l_tri.append( QgsTriangle( pts.at( n ), pts.at( 0 ), mCenter ) );
238
239 return l_tri;
240}
241
243{
244 // TODO: inclined circle
245 return QgsCircle( mCenter, apothem() );
246}
247
249{
250 // TODO: inclined circle
251 return QgsCircle( mCenter, mRadius );
252}
253
254QString QgsRegularPolygon::toString( int pointPrecision, int radiusPrecision, int anglePrecision ) const
255{
256 QString rep;
257 if ( isEmpty() )
258 rep = u"Empty"_s;
259 else
260 rep = u"RegularPolygon (Center: %1, First Vertex: %2, Radius: %3, Azimuth: %4)"_s.arg( mCenter.asWkt( pointPrecision ), 0, 's' )
261 .arg( mFirstVertex.asWkt( pointPrecision ), 0, 's' )
262 .arg( qgsDoubleToString( mRadius, radiusPrecision ), 0, 'f' )
263 .arg( qgsDoubleToString( mCenter.azimuth( mFirstVertex ), anglePrecision ), 0, 'f' );
264 // TODO: inclination
265 // .arg( qgsDoubleToString( mCenter.inclination(mFirstVertex), anglePrecision ), 0, 'f' );
266
267 return rep;
268}
269
271{
272 if ( isEmpty() )
273 {
274 return 0.0;
275 }
276
277 return ( mRadius * mRadius * mNumberSides * std::sin( centralAngle() * M_PI / 180.0 ) ) / 2;
278}
279
281{
282 if ( isEmpty() )
283 {
284 return 0.0;
285 }
286
287 return length() * mNumberSides;
288}
289
291{
292 if ( isEmpty() )
293 {
294 return 0.0;
295 }
296
297 return mRadius * 2 * std::sin( M_PI / mNumberSides );
298}
299
300double QgsRegularPolygon::apothemToRadius( const double apothem, const unsigned int numSides ) const
301{
302 return apothem / std::cos( M_PI / numSides );
303}
304
305double QgsRegularPolygon::interiorAngle( const unsigned int nbSides ) const
306{
307 return ( nbSides - 2 ) * 180 / nbSides;
308}
309
310double QgsRegularPolygon::centralAngle( const unsigned int nbSides ) const
311{
312 return 360.0 / nbSides;
313}
314
316{
317 return interiorAngle( mNumberSides );
318}
319
321{
322 return centralAngle( mNumberSides );
323}
Circle geometry type.
Definition qgscircle.h:46
static QgsPoint midpoint(const QgsPoint &pt1, const QgsPoint &pt2)
Returns a middle point between points pt1 and pt2.
Line string geometry type, with support for z-dimension and m-values.
Point geometry type, with support for z-dimension and m-values.
Definition qgspoint.h:53
double azimuth(const QgsPoint &other) const
Calculates Cartesian azimuth between this point and other one (clockwise in degree,...
Definition qgspoint.cpp:717
double distance(double x, double y) const
Returns the Cartesian 2D distance between this point and a specified x, y coordinate.
Definition qgspoint.h:466
QgsPoint project(double distance, double azimuth, double inclination=90.0) const
Returns a new point which corresponds to this point projected by a specified distance with specified ...
Definition qgspoint.cpp:734
Polygon geometry type.
Definition qgspolygon.h:37
QgsPointSequence points() const
Returns a list including the vertices of the regular polygon.
QString toString(int pointPrecision=17, int radiusPrecision=17, int anglePrecision=2) const
Returns a string representation of the regular polygon.
QgsRegularPolygon()=default
Constructor for QgsRegularPolygon.
double interiorAngle() const
Returns the measure of the interior angles in degrees.
QgsPoint center() const
Returns the center point of the regular polygon.
QgsCircle circumscribedCircle() const
Returns the circumscribed circle.
QgsPoint firstVertex() const
Returns the first vertex (corner) of the regular polygon.
QgsLineString * toLineString() const
Returns as a linestring.
ConstructionOption
A regular polygon can be constructed inscribed in a circle or circumscribed about a circle.
@ CircumscribedCircle
Circumscribed about a circle (the radius is the distance from the center to the midpoints of the side...
@ InscribedCircle
Inscribed in a circle (the radius is the distance between the center and vertices).
double length() const
Returns the length of a side.
double perimeter() const
Returns the perimeter.
QgsTriangle toTriangle() const
Returns as a triangle.
double radius() const
Returns the radius.
void setNumberSides(unsigned int numberSides)
Sets the number of sides.
void setCenter(const QgsPoint &center)
Sets the center point.
QgsPolygon * toPolygon() const
Returns as a polygon.
bool operator==(const QgsRegularPolygon &rp) const
bool operator!=(const QgsRegularPolygon &rp) const
double area() const
Returns the area.
bool isEmpty() const
A regular polygon is empty if radius equal to 0 or number of sides < 3.
double apothem() const
Returns the apothem of the regular polygon.
void setRadius(double radius)
Sets the radius.
QVector< QgsTriangle > triangulate() const
Returns a triangulation (vertices from sides to the center) of the regular polygon.
double centralAngle() const
Returns the measure of the central angle (the angle subtended at the center of the polygon by one of ...
void setFirstVertex(const QgsPoint &firstVertex)
Sets the first vertex.
QgsCircle inscribedCircle() const
Returns the inscribed circle.
Triangle geometry type.
Definition qgstriangle.h:33
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Definition qgis.h:6893
QVector< QgsPoint > QgsPointSequence