Skip to content
Permalink
Browse files

Some QgsPoint improvements

- Modernize QgsVector, improve docs, add some methods missing from
Python bindings
- Add method to QgsPoint to project a point by a specified distance
and bearing
- Add distance methods to complement existing sqrDist squared distance
methods
- Rename QgsVector::normal to normalized (avoid confusion with normal
vectors)
- Add more QgsPoint operators
- Add some more QgsPoint and QgsVector tests
  • Loading branch information
nyalldawson committed Apr 6, 2016
1 parent 3a1f6c4 commit 2e44c1191400f0ffed36fbd12d9c547fa8c0ced4
@@ -10,28 +10,76 @@ class QgsVector
%End

public:

/** Default constructor for QgsVector. Creates a vector with length of 0.0.
*/
QgsVector();

/** Constructor for QgsVector taking x and y component values.
* @param x x-component
* @param y y-component
*/
QgsVector( double x, double y );

//! @note not available in Python bindings
//QgsVector operator-( void ) const;
//! Swaps the sign of the x and y components of the vector.
QgsVector operator-() const;

/** Returns a vector where the components have been multiplied by a scalar value.
* @param scalar factor to multiply by
*/
QgsVector operator*( double scalar ) const;

/** Returns a vector where the components have been divided by a scalar value.
* @param scalar factor to divide by
*/
QgsVector operator/( double scalar ) const;

/** Returns the sum of the x component of this vector multiplied by the x component of another
* vector plus the y component of this vector multipled by the y component of another vector.
*/
double operator*( QgsVector v ) const;

/** Returns the length of the vector.
*/
double length() const;

/** Returns the vector's x-component.
* @see y()
*/
double x() const;

/** Returns the vector's y-component.
* @see x()
*/
double y() const;

// perpendicular vector (rotated 90 degrees counter-clockwise)
/** Returns the perpendicular vector to this vector (rotated 90 degrees counter-clockwise)
*/
QgsVector perpVector() const;

//! @note not available in Python bindings
//double angle( void ) const;
/** Returns the angle of the vector in radians.
*/
double angle() const;

/** Returns the angle between this vector and another vector in radians.
*/
double angle( QgsVector v ) const;

/** Rotates the vector by a specified angle.
* @param rot angle in radians
*/
QgsVector rotateBy( double rot ) const;
QgsVector normal() const;

/** Returns the vector's normalized (or "unit") vector (ie same angle but length of 1.0). Will throw an expection
* if called on a vector with length of 0.
* @deprecated use normalized() instead
*/
QgsVector normal() const /Deprecated/;

/** Returns the vector's normalized (or "unit") vector (ie same angle but length of 1.0). Will throw an expection
* if called on a vector with length of 0.
*/
QgsVector normalized() const;
};


@@ -138,17 +186,44 @@ class QgsPoint
*/
QString wellKnownText() const;

/** Returns the squared distance between this point and x,y*/
/** Returns the squared distance between this point a specified x, y coordinate.
* @see distance()
*/
double sqrDist( double x, double y ) const;

/** Returns the squared distance between this and other point*/
/** Returns the squared distance between this point another point.
* @see distance()
*/
double sqrDist( const QgsPoint& other ) const;

/** Returns the distance between this point and a specified x, y coordinate.
* @param x x-coordniate
* @param y y-coordinate
* @see sqrDist()
* @note added in QGIS 2.16
*/
double distance( double x, double y ) const;

/** Returns the distance between this point and another point.
* @param other other point
* @see sqrDist()
* @note added in QGIS 2.16
*/
double distance( const QgsPoint& other ) const;

/** Returns the minimum distance between this point and a segment */
double sqrDistToSegment( double x1, double y1, double x2, double y2, QgsPoint& minDistPoint /Out/, double epsilon = DEFAULT_SEGMENT_EPSILON ) const;

/** Calculates azimuth between this point and other one (clockwise in degree, starting from north) */
double azimuth( const QgsPoint& other );
double azimuth( const QgsPoint& other ) const;

/** Returns a new point which correponds to this point projected by a specified distance
* in a specified bearing.
* @param distance distance to project
* @param bearing angle to project in, clockwise in degrees starting from north
* @note added in QGIS 2.16
*/
QgsPoint project( double distance, double bearing ) const;

/** Compares this point with another point with a fuzzy tolerance
* @param other point to compare with
@@ -173,6 +248,33 @@ class QgsPoint
//! 3 if point is on open ray b.
int onSegment( const QgsPoint& a, const QgsPoint& b ) const;

//! Calculates the vector obtained by subtracting a point from this point
QgsVector operator-( const QgsPoint& p ) const;

//! Adds a vector to this point in place
QgsPoint &operator+=( QgsVector v );

//! Subtracts a vector from this point in place
QgsPoint &operator-=( QgsVector v );

//! Adds a vector to this point
QgsPoint operator+( QgsVector v ) const;

//! Subtracts a vector from this point
QgsPoint operator-( QgsVector v ) const;

//! Multiplies the coordinates in this point by a scalar quantity
QgsPoint operator*( double scalar ) const;

//! Divides the coordinates in this point by a scalar quantity
QgsPoint operator/( double scalar ) const;

//! Multiplies the coordinates in this point by a scalar quantity in place
QgsPoint &operator*=( double scalar );

//! Divides the coordinates in this point by a scalar quantity in place
QgsPoint &operator/=( double scalar );

SIP_PYOBJECT __repr__();
%MethodCode
QString str = "(" + QString::number(sipCpp->x()) + "," + QString::number(sipCpp->y()) + ")";
@@ -28,22 +28,26 @@
// QgsVector
//

QgsVector::QgsVector() : m_x( 0.0 ), m_y( 0.0 )
QgsVector::QgsVector()
: mX( 0.0 )
, mY( 0.0 )
{
}

QgsVector::QgsVector( double x, double y ) : m_x( x ), m_y( y )
QgsVector::QgsVector( double x, double y )
: mX( x )
, mY( y )
{
}

QgsVector QgsVector::operator-( void ) const
QgsVector QgsVector::operator-() const
{
return QgsVector( -m_x, -m_y );
return QgsVector( -mX, -mY );
}

QgsVector QgsVector::operator*( double scalar ) const
{
return QgsVector( m_x * scalar, m_y * scalar );
return QgsVector( mX * scalar, mY * scalar );
}

QgsVector QgsVector::operator/( double scalar ) const
@@ -53,33 +57,32 @@ QgsVector QgsVector::operator/( double scalar ) const

double QgsVector::operator*( QgsVector v ) const
{
return m_x * v.m_x + m_y * v.m_y;
return mX * v.mX + mY * v.mY;
}

double QgsVector::length() const
{
return sqrt( m_x * m_x + m_y * m_y );
return sqrt( mX * mX + mY * mY );
}

double QgsVector::x() const
{
return m_x;
return mX;
}

double QgsVector::y() const
{
return m_y;
return mY;
}

// perpendicular vector (rotated 90 degrees counter-clockwise)
QgsVector QgsVector::perpVector() const
{
return QgsVector( -m_y, m_x );
return QgsVector( -mY, mX );
}

double QgsVector::angle( void ) const
double QgsVector::angle() const
{
double ang = atan2( m_y, m_x );
double ang = atan2( mY, mX );
return ang < 0.0 ? ang + 2.0 * M_PI : ang;
}

@@ -90,18 +93,23 @@ double QgsVector::angle( QgsVector v ) const

QgsVector QgsVector::rotateBy( double rot ) const
{
double ang = atan2( m_y, m_x ) + rot;
double ang = atan2( mY, mX ) + rot;
double len = length();
return QgsVector( len * cos( ang ), len * sin( ang ) );
}

QgsVector QgsVector::normal() const
{
return normalized();
}

QgsVector QgsVector::normalized() const
{
double len = length();

if ( len == 0.0 )
{
throw QgsException( "normal vector of null vector undefined" );
throw QgsException( "normalized vector of null vector undefined" );
}

return *this / len;
@@ -352,13 +360,31 @@ double QgsPoint::sqrDist( const QgsPoint& other ) const
return sqrDist( other.x(), other.y() );
}

double QgsPoint::azimuth( const QgsPoint& other )
double QgsPoint::distance( double x, double y ) const
{
return sqrt( sqrDist( x, y ) );
}

double QgsPoint::distance( const QgsPoint& other ) const
{
return sqrt( sqrDist( other ) );
}

double QgsPoint::azimuth( const QgsPoint& other ) const
{
double dx = other.x() - m_x;
double dy = other.y() - m_y;
return ( atan2( dx, dy ) * 180.0 / M_PI );
}

QgsPoint QgsPoint::project( double distance, double bearing ) const
{
double rads = bearing * M_PI / 180.0;
double dx = distance * sin( rads );
double dy = distance * cos( rads );
return QgsPoint( m_x + dx, m_y + dy );
}

bool QgsPoint::compare( const QgsPoint &other, double epsilon ) const
{
return ( qgsDoubleNear( m_x, other.x(), epsilon ) && qgsDoubleNear( m_y, other.y(), epsilon ) );

0 comments on commit 2e44c11

Please sign in to comment.
You can’t perform that action at this time.