2021-03-12 21:33:46 +00:00
|
|
|
#ifndef SDLPP_HPP_GEOMETRY_LINE
|
|
|
|
#define SDLPP_HPP_GEOMETRY_LINE
|
|
|
|
|
|
|
|
#include "sdlpp_common.hpp"
|
|
|
|
#include "sdlpp_vector.hpp"
|
|
|
|
#include "sdlpp_line.hpp"
|
|
|
|
#include <algorithm>
|
2021-03-13 14:05:16 +00:00
|
|
|
#include <iostream>
|
2021-03-12 21:33:46 +00:00
|
|
|
|
|
|
|
namespace SDLPP {
|
2021-03-13 14:05:16 +00:00
|
|
|
template < typename T >
|
|
|
|
Vec2D< T > pointProjectionOnLine( const Vec2D< T > &point,
|
|
|
|
const Line< T > &line ) {
|
2021-03-12 21:33:46 +00:00
|
|
|
/* 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() );
|
|
|
|
}
|
2021-03-13 14:05:16 +00:00
|
|
|
template < typename T >
|
|
|
|
double pointLineDistance( const Vec2D< T > &point, const Line< T > &line ) {
|
2021-03-12 21:33:46 +00:00
|
|
|
return vecDistance( point, pointProjectionOnLine( point, line ) );
|
|
|
|
}
|
2021-03-13 14:05:16 +00:00
|
|
|
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;
|
|
|
|
}
|
2021-03-12 21:33:46 +00:00
|
|
|
} // namespace SDLPP
|
|
|
|
|
|
|
|
#endif
|