1 /*************************************************************************** 2 qgslinesegment.h 3 ----------------- 4 begin : April 2018 5 copyright : (C) 2018 by Nyall Dawson 6 email : nyall dot dawson at gmail dot com 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 QGSLINESEGMENT_H 19 #define QGSLINESEGMENT_H 20 21 #include "qgis_core.h" 22 #include "qgspointxy.h" 23 24 class QgsLineString; 25 26 /** 27 * \ingroup core 28 * \brief Represents a single 2D line segment, consisting of a 2D start and end vertex only. 29 * \since QGIS 3.2 30 */ 31 class CORE_EXPORT QgsLineSegment2D 32 { 33 34 public: 35 36 /** 37 * Constructor for a QgsLineSegment2D from the specified \a start point to 38 * the \a end point. 39 */ QgsLineSegment2D(const QgsPointXY & start,const QgsPointXY & end)40 QgsLineSegment2D( const QgsPointXY &start, const QgsPointXY &end ) SIP_HOLDGIL 41 : mStart( start ) 42 , mEnd( end ) 43 {} 44 45 /** 46 * Constructor for a QgsLineSegment2D from the point (\a x1, \a y2) to 47 * (\a x2, \a y2). 48 */ QgsLineSegment2D(double x1,double y1,double x2,double y2)49 QgsLineSegment2D( double x1, double y1, double x2, double y2 ) SIP_HOLDGIL 50 : mStart( QgsPointXY( x1, y1 ) ) 51 , mEnd( QgsPointXY( x2, y2 ) ) 52 {} 53 54 /** 55 * Returns the length of the segment. 56 * \see lengthSquared() 57 */ length()58 double length() const SIP_HOLDGIL 59 { 60 return std::sqrt( ( mStart.x() - mEnd.x() ) * ( mStart.x() - mEnd.x() ) + ( mStart.y() - mEnd.y() ) * ( mStart.y() - mEnd.y() ) ); 61 } 62 63 /** 64 * Returns the squared length of the segment. 65 * \see length() 66 */ lengthSquared()67 double lengthSquared() const SIP_HOLDGIL 68 { 69 return ( mStart.x() - mEnd.x() ) * ( mStart.x() - mEnd.x() ) + ( mStart.y() - mEnd.y() ) * ( mStart.y() - mEnd.y() ); 70 } 71 72 /** 73 * Returns the segment's start x-coordinate. 74 * \see start() 75 * \see startY() 76 */ startX()77 double startX() const SIP_HOLDGIL 78 { 79 return mStart.x(); 80 } 81 82 /** 83 * Returns the segment's start y-coordinate. 84 * \see start() 85 * \see startX() 86 */ startY()87 double startY() const SIP_HOLDGIL 88 { 89 return mStart.y(); 90 } 91 92 /** 93 * Returns the segment's end x-coordinate. 94 * \see end() 95 * \see endY() 96 */ endX()97 double endX() const SIP_HOLDGIL 98 { 99 return mEnd.x(); 100 } 101 102 /** 103 * Returns the segment's end y-coordinate. 104 * \see end() 105 * \see endX() 106 */ endY()107 double endY() const SIP_HOLDGIL 108 { 109 return mEnd.y(); 110 } 111 112 /** 113 * Returns the segment's start point. 114 * \see end() 115 * \see startX() 116 * \see startY() 117 */ start()118 QgsPointXY start() const SIP_HOLDGIL 119 { 120 return mStart; 121 } 122 123 /** 124 * Returns the segment's end point. 125 * \see start() 126 * \see endX() 127 * \see endY() 128 */ end()129 QgsPointXY end() const SIP_HOLDGIL 130 { 131 return mEnd; 132 } 133 134 /** 135 * Sets the segment's start \a x coordinate. 136 * \see setEndX() 137 * \see setStart() 138 * \see setStartY() 139 */ setStartX(double x)140 void setStartX( double x ) SIP_HOLDGIL 141 { 142 mStart.setX( x ); 143 } 144 145 /** 146 * Sets the segment's start \a y coordinate. 147 * \see setEndY() 148 * \see setStart() 149 * \see setStartX() 150 */ setStartY(double y)151 void setStartY( double y ) SIP_HOLDGIL 152 { 153 mStart.setY( y ); 154 } 155 156 /** 157 * Sets the segment's end \a x coordinate. 158 * \see setStartX() 159 * \see setEnd() 160 * \see setEndY() 161 */ setEndX(double x)162 void setEndX( double x ) SIP_HOLDGIL 163 { 164 mEnd.setX( x ); 165 } 166 167 /** 168 * Sets the segment's end \a y coordinate. 169 * \see setStartY() 170 * \see setEnd() 171 * \see setEndX() 172 */ setEndY(double y)173 void setEndY( double y ) SIP_HOLDGIL 174 { 175 mEnd.setY( y ); 176 } 177 178 /** 179 * Sets the segment's \a start point. 180 * \see setStartX() 181 * \see setStartY() 182 * \see setEnd() 183 */ setStart(const QgsPointXY & start)184 void setStart( const QgsPointXY &start ) SIP_HOLDGIL 185 { 186 mStart = start; 187 } 188 189 /** 190 * Sets the segment's \a end point. 191 * \see setEndX() 192 * \see setEndY() 193 * \see setStart() 194 */ setEnd(const QgsPointXY & end)195 void setEnd( const QgsPointXY &end ) SIP_HOLDGIL 196 { 197 mEnd = end; 198 } 199 200 /** 201 * Tests if a \a point is to the left of the line segment. 202 * 203 * Returns -1 if the point falls to the left of the line, or +1 if the point 204 * is to the right. 205 * 206 * If the return value is 0, then the test was unsuccessful (e.g. due to testing a point exactly 207 * on the line, or exactly in line with the segment) and the result is undefined. 208 * 209 * \see QgsGeometryUtils::leftOfLine() 210 */ 211 int pointLeftOfLine( const QgsPointXY &point ) const SIP_HOLDGIL; 212 213 /** 214 * Reverses the line segment, so that the start and end points are flipped. 215 */ reverse()216 void reverse() SIP_HOLDGIL 217 { 218 std::swap( mStart, mEnd ); 219 } 220 221 // TODO c++20 - replace with = default 222 223 //! Equality operator 224 bool operator==( const QgsLineSegment2D &other ) const SIP_HOLDGIL 225 { 226 return mStart == other.mStart && mEnd == other.mEnd; 227 } 228 229 //! Inequality operator 230 bool operator!=( const QgsLineSegment2D &other ) const SIP_HOLDGIL 231 { 232 return mStart != other.mStart || mEnd != other.mEnd; 233 } 234 235 private: 236 237 QgsPointXY mStart; 238 QgsPointXY mEnd; 239 240 }; 241 242 #endif // QGSLINESEGMENT_H 243