00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "qgspoint.h"
00021 #include <cmath>
00022 #include <QTextStream>
00023 #include <QObject>
00024
00025 #include "qgsexception.h"
00026
00027
00028
00029
00030
00031 QgsVector::QgsVector() : m_x( 0.0 ), m_y( 0.0 )
00032 {
00033 }
00034
00035 QgsVector::QgsVector( double x, double y ) : m_x( x ), m_y( y )
00036 {
00037 }
00038
00039 QgsVector QgsVector::operator-( void ) const
00040 {
00041 return QgsVector( -m_x, -m_y );
00042 }
00043
00044 QgsVector QgsVector::operator*( double scalar ) const
00045 {
00046 return QgsVector( m_x*scalar, m_y*scalar );
00047 }
00048
00049 QgsVector QgsVector::operator/( double scalar ) const
00050 {
00051 return *this * ( 1.0 / scalar );
00052 }
00053
00054 double QgsVector::operator*( QgsVector v ) const
00055 {
00056 return m_x*v.m_x + m_y*v.m_y;
00057 }
00058
00059 double QgsVector::length() const
00060 {
00061 return sqrt( m_x*m_x + m_y*m_y );
00062 }
00063
00064 double QgsVector::x() const
00065 {
00066 return m_x;
00067 }
00068
00069 double QgsVector::y() const
00070 {
00071 return m_y;
00072 }
00073
00074
00075 QgsVector QgsVector::perpVector() const
00076 {
00077 return QgsVector( -m_y, m_x );
00078 }
00079
00080 double QgsVector::angle( void ) const
00081 {
00082 double ang = atan2( m_y, m_x );
00083 return ang < 0.0 ? ang + 2.0*M_PI : ang;
00084 }
00085
00086 double QgsVector::angle( QgsVector v ) const
00087 {
00088 return v.angle() - angle();
00089 }
00090
00091 QgsVector QgsVector::rotateBy( double rot ) const
00092 {
00093 double ang = atan2( m_y, m_x ) + rot;
00094 double len = length();
00095 return QgsVector( len*cos( ang ), len*sin( ang ) );
00096 }
00097
00098 QgsVector QgsVector::normal() const
00099 {
00100 double len = length();
00101
00102 if ( len == 0.0 )
00103 {
00104 throw QgsException( "normal vector of null vector undefined" );
00105 }
00106
00107 return *this / len;
00108 }
00109
00110
00111
00112
00113
00114
00115 QgsPoint::QgsPoint( const QgsPoint& p )
00116 {
00117 m_x = p.x();
00118 m_y = p.y();
00119 }
00120
00121 QString QgsPoint::toString() const
00122 {
00123 QString rep;
00124 QTextStream ot( &rep );
00125 ot.setRealNumberPrecision( 12 );
00126 ot << m_x << ", " << m_y;
00127 return rep;
00128 }
00129
00130 QString QgsPoint::toString( int thePrecision ) const
00131 {
00132 QString rep = QString::number( m_x, 'f', thePrecision ) + QString( "," ) +
00133 QString::number( m_y, 'f', thePrecision );
00134 return rep;
00135 }
00136
00137 QString QgsPoint::toDegreesMinutesSeconds( int thePrecision ) const
00138 {
00139 int myDegreesX = int( std::abs( m_x ) );
00140 float myFloatMinutesX = float(( std::abs( m_x ) - myDegreesX ) * 60 );
00141 int myIntMinutesX = int( myFloatMinutesX );
00142 float mySecondsX = float( myFloatMinutesX - myIntMinutesX ) * 60;
00143
00144 int myDegreesY = int( std::abs( m_y ) );
00145 float myFloatMinutesY = float(( std::abs( m_y ) - myDegreesY ) * 60 );
00146 int myIntMinutesY = int( myFloatMinutesY );
00147 float mySecondsY = float( myFloatMinutesY - myIntMinutesY ) * 60;
00148
00149 QString myXHemisphere = m_x < 0 ? QObject::tr( "W" ) : QObject::tr( "E" );
00150 QString myYHemisphere = m_y < 0 ? QObject::tr( "S" ) : QObject::tr( "N" );
00151 QString rep = QString::number( myDegreesX ) + QChar( 176 ) +
00152 QString::number( myIntMinutesX ) + QString( "'" ) +
00153 QString::number( mySecondsX, 'f', thePrecision ) + QString( "\"" ) +
00154 myXHemisphere + QString( "," ) +
00155 QString::number( myDegreesY ) + QChar( 176 ) +
00156 QString::number( myIntMinutesY ) + QString( "'" ) +
00157 QString::number( mySecondsY, 'f', thePrecision ) + QString( "\"" ) +
00158 myYHemisphere;
00159 return rep;
00160 }
00161
00162
00163 QString QgsPoint::wellKnownText() const
00164 {
00165 return QString( "POINT(%1 %2)" ).arg( QString::number( m_x, 'f', 18 ) ).arg( QString::number( m_y, 'f', 18 ) );
00166 }
00167
00168 double QgsPoint::sqrDist( double x, double y ) const
00169 {
00170 return ( m_x - x )*( m_x - x ) + ( m_y - y )*( m_y - y );
00171 }
00172
00173 double QgsPoint::sqrDist( const QgsPoint& other ) const
00174 {
00175 return sqrDist( other.x(), other.y() );
00176 }
00177
00178
00179 bool QgsPoint::operator==( const QgsPoint & other )
00180 {
00181 if (( m_x == other.x() ) && ( m_y == other.y() ) )
00182 return true;
00183 else
00184 return false;
00185 }
00186
00187 bool QgsPoint::operator!=( const QgsPoint & other ) const
00188 {
00189 if (( m_x == other.x() ) && ( m_y == other.y() ) )
00190 return false;
00191 else
00192 return true;
00193 }
00194
00195 QgsPoint & QgsPoint::operator=( const QgsPoint & other )
00196 {
00197 if ( &other != this )
00198 {
00199 m_x = other.x();
00200 m_y = other.y();
00201 }
00202
00203 return *this;
00204 }
00205
00206 void QgsPoint::multiply( const double& scalar )
00207 {
00208 m_x *= scalar;
00209 m_y *= scalar;
00210 }
00211
00212 int QgsPoint::onSegment( const QgsPoint& a, const QgsPoint& b ) const
00213 {
00214
00215 if (
00216 fabs(( b.y() - a.y() ) *( m_x - a.x() ) - ( m_y - a.y() ) *( b.x() - a.x() ) )
00217 >= qMax( fabs( b.x() - a.x() ), fabs( b.y() - a.y() ) )
00218 )
00219 {
00220 return 0;
00221 }
00222 if (( b.x() < a.x() && a.x() < m_x ) || ( b.y() < a.y() && a.y() < m_y ) )
00223 {
00224 return 1;
00225 }
00226 if (( m_x < a.x() && a.x() < b.x() ) || ( m_y < a.y() && a.y() < b.y() ) )
00227 {
00228 return 1;
00229 }
00230 if (( a.x() < b.x() && b.x() < m_x ) || ( a.y() < b.y() && b.y() < m_y ) )
00231 {
00232 return 3;
00233 }
00234 if (( m_x < b.x() && b.x() < a.x() ) || ( m_y < b.y() && b.y() < a.y() ) )
00235 {
00236 return 3;
00237 }
00238
00239 return 2;
00240 }
00241
00242 double QgsPoint::sqrDistToSegment( double x1, double y1, double x2, double y2, QgsPoint& minDistPoint ) const
00243 {
00244 double nx, ny;
00245
00246 nx = y2 - y1;
00247 ny = -( x2 - x1 );
00248
00249 double t;
00250 t = ( m_x * ny - m_y * nx - x1 * ny + y1 * nx ) / (( x2 - x1 ) * ny - ( y2 - y1 ) * nx );
00251
00252 if ( t < 0.0 )
00253 {
00254 minDistPoint.setX( x1 );
00255 minDistPoint.setY( y1 );
00256 }
00257 else if ( t > 1.0 )
00258 {
00259 minDistPoint.setX( x2 );
00260 minDistPoint.setY( y2 );
00261 }
00262 else
00263 {
00264 minDistPoint.setX( x1 + t *( x2 - x1 ) );
00265 minDistPoint.setY( y1 + t *( y2 - y1 ) );
00266 }
00267
00268 return ( sqrDist( minDistPoint ) );
00269 }