#ifndef SDLPP_HPP_GEOMETRY_LINE #define SDLPP_HPP_GEOMETRY_LINE #include "sdlpp_common.hpp" #include "sdlpp_vector.hpp" #include "sdlpp_line.hpp" #include #include namespace SDLPP { template < typename T > Vec2D< T > pointProjectionOnLine( const Vec2D< T > &point, const Line< T > &line ) { /* from here - * https://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment */ auto length_squared = line.lengthSquared(); if ( length_squared == 0.0 ) return point; auto t = std::max( 0.0, std::min( 1.0, ( ( point - line.getStart() ) * ( line.getEnd() - line.getStart() ) ) / length_squared ) ); return line.getStart() + t * ( line.getEnd() - line.getStart() ); } template < typename T > double pointLineDistance( const Vec2D< T > &point, const Line< T > &line ) { return vecDistance( point, pointProjectionOnLine( point, line ) ); } template < typename T > int _determinant( const Line< T > &line, const Vec2D< T > &point ) { auto res = ( line.getEnd().getX() - line.getStart().getX() ) * ( point.getY() - line.getStart().getY() ) - ( line.getEnd().getY() - line.getStart().getY() ) * ( point.getX() - line.getStart().getX() ); if ( res < 0 ) return -1; if ( res > 0 ) return 1; return 0; } template < typename T > bool linesCross( const Line< T > &a, const Line< T > &b ) { auto det_a_s = _determinant( a, b.getStart() ); auto det_a_e = _determinant( a, b.getEnd() ); if ( det_a_s == det_a_e && det_a_s != 0 ) return false; // det_a_s == det_a_e == 0, means that lines have the same vector, // we need to find out if they overlap if ( det_a_s == det_a_e ) { if ( a.getStart().getX() == a.getEnd().getX() ) { // vertical lines return a.bottomost().getY() > b.topmost().getY() && a.topmost().getY() < b.bottomost().getY(); } else { // horizontal lines return a.leftmost().getX() < b.rightmost().getX() && a.rightmost().getX() > b.leftmost().getX(); } } auto det_b_s = _determinant( b, a.getStart() ); auto det_b_e = _determinant( b, a.getEnd() ); if ( det_b_s == det_b_e ) return false; return true; } } // namespace SDLPP #endif