bool QgsRay2D::intersects( const QgsLineSegment2D &segment, QgsPointXY &intersectPoint ) const { const QgsVector ao = origin - segment.start(); const QgsVector ab = segment.end() - segment.start(); const double det = ab.crossProduct( direction ); if ( qgsDoubleNear( det, 0.0 ) ) { const int abo = segment.pointLeftOfLine( origin ); if ( abo != 0 ) { return false; } else { const double distA = ao * direction; const double distB = ( origin - segment.end() ) * direction; if ( distA > 0 && distB > 0 ) { return false; } else { if ( ( distA > 0 ) != ( distB > 0 ) ) intersectPoint = origin; else if ( distA > distB ) // at this point, both distances are negative intersectPoint = segment.start(); // hence the nearest point is A else intersectPoint = segment.end(); return true; } } } else { const double u = ao.crossProduct( direction ) / det; if ( u < 0.0 || 1.0 < u ) { return false; } else { const double t = -ab.crossProduct( ao ) / det; intersectPoint = origin + direction * t; return qgsDoubleNear( t, 0.0 ) || t > 0; } } }
bool QgsClockwiseAngleComparer::operator()( const QgsPointXY &a, const QgsPointXY &b ) const { const bool aIsLeft = a.x() < mVertex.x(); const bool bIsLeft = b.x() < mVertex.x(); if ( aIsLeft != bIsLeft ) return bIsLeft; if ( qgsDoubleNear( a.x(), mVertex.x() ) && qgsDoubleNear( b.x(), mVertex.x() ) ) { if ( a.y() >= mVertex.y() || b.y() >= mVertex.y() ) { return b.y() < a.y(); } else { return a.y() < b.y(); } } else { const QgsVector oa = a - mVertex; const QgsVector ob = b - mVertex; const double det = oa.crossProduct( ob ); if ( qgsDoubleNear( det, 0.0 ) ) { return oa.lengthSquared() < ob.lengthSquared(); } else { return det < 0; } } }