geometry: SEG::NearestPoint(SEG) now returns points only on (this) segment

This commit is contained in:
Tomasz Wlostowski 2020-10-07 15:15:53 +02:00
parent 1ef120ff4f
commit d6fa81036b
1 changed files with 52 additions and 11 deletions

View File

@ -36,10 +36,26 @@ int sgn( T aVal )
SEG::ecoord SEG::SquaredDistance( const SEG& aSeg ) const SEG::ecoord SEG::SquaredDistance( const SEG& aSeg ) const
{ {
VECTOR2I closestOnRef = NearestPoint( aSeg ); // fixme: rather inefficient....
VECTOR2I closestOnASeg = aSeg.NearestPoint( *this ); if( Intersect( aSeg ) )
return 0;
return ( closestOnRef - closestOnASeg ).SquaredEuclideanNorm(); const VECTOR2I pts[4] =
{
aSeg.NearestPoint( A ) - A,
aSeg.NearestPoint( B ) - B,
NearestPoint( aSeg.A ) - aSeg.A,
NearestPoint( aSeg.B ) - aSeg.B
};
ecoord m = VECTOR2I::ECOORD_MAX;
for( int i = 0; i < 4; i++ )
{
m = std::min( m, pts[i].SquaredEuclideanNorm() );
}
return m;
} }
@ -48,15 +64,40 @@ const VECTOR2I SEG::NearestPoint( const SEG& aSeg ) const
if( OPT_VECTOR2I p = Intersect( aSeg ) ) if( OPT_VECTOR2I p = Intersect( aSeg ) )
return *p; return *p;
VECTOR2I nearestA = NearestPoint( aSeg.A ); const VECTOR2I pts_origin[4] =
VECTOR2I deltaA = nearestA - aSeg.A; {
VECTOR2I nearestB = NearestPoint( aSeg.B ); aSeg.NearestPoint( A ),
VECTOR2I deltaB = nearestB - aSeg.B; aSeg.NearestPoint( B ),
NearestPoint( aSeg.A ),
NearestPoint( aSeg.B )
};
if( deltaA.SquaredEuclideanNorm() < deltaB.SquaredEuclideanNorm() )
return nearestA; const VECTOR2I* pts_out[4] =
else {
return nearestB; &A,
&B,
&pts_origin[2],
&pts_origin[3]
};
const ecoord pts_dist[4] =
{
( pts_origin[0] - A ).SquaredEuclideanNorm(),
( pts_origin[1] - B ).SquaredEuclideanNorm(),
( pts_origin[2] - aSeg.A ).SquaredEuclideanNorm(),
( pts_origin[3] - aSeg.B ).SquaredEuclideanNorm()
};
int min_i = 0;
for( int i = 0; i < 4; i++ )
{
if( pts_dist[i] < pts_dist[min_i] )
min_i = i;
}
return *pts_out[min_i];
} }