geometry: SEG::NearestPoint(SEG) now returns points only on (this) segment
This commit is contained in:
parent
1ef120ff4f
commit
d6fa81036b
|
@ -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];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue