mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-04-14 13:19:34 +00:00
Modify previous commit to correct logic
We are calculating the same value in two different ways. If there is an off-by-one issue in our calculation along axis, this still means that it was a direct hit on the line as seen in the unit test cases
This commit is contained in:
parent
f3bbf2b7bd
commit
fba2b7a04a
@ -399,8 +399,8 @@ int SEG::Distance( const VECTOR2I& aP ) const
|
||||
|
||||
SEG::ecoord SEG::SquaredDistance( const VECTOR2I& aP ) const
|
||||
{
|
||||
VECTOR2L ab = VECTOR2L( B.x - A.x, B.y - A.y );
|
||||
VECTOR2L ap = VECTOR2L( aP.x - A.x, aP.y - A.y );
|
||||
VECTOR2L ab = VECTOR2L( B ) - A;
|
||||
VECTOR2L ap = VECTOR2L( aP ) - A;
|
||||
|
||||
ecoord e = ap.Dot( ab );
|
||||
|
||||
@ -410,18 +410,18 @@ SEG::ecoord SEG::SquaredDistance( const VECTOR2I& aP ) const
|
||||
ecoord f = ab.SquaredEuclideanNorm();
|
||||
|
||||
if( e >= f )
|
||||
return VECTOR2L( aP.x - B.x, aP.y - B.y ).SquaredEuclideanNorm();
|
||||
return ( VECTOR2L( aP ) - B ).Dot( VECTOR2L( aP ) - B );
|
||||
|
||||
const double g = ( double( e ) * e ) / f;
|
||||
const double g = ap.SquaredEuclideanNorm() - ( double( e ) * e ) / f;
|
||||
|
||||
//Squared distance can't be negative
|
||||
if( g > ap.SquaredEuclideanNorm() )
|
||||
{
|
||||
return (ecoord) std::numeric_limits<std::int32_t>::max()
|
||||
* std::numeric_limits<std::int32_t>::max();
|
||||
}
|
||||
// The only way g can be negative is if there was a rounding error since
|
||||
// e is the projection of aP onto ab and therefore cannot be greater than
|
||||
// the length of ap and f is guaranteed to be greater than e, meaning
|
||||
// e * e / f cannot be greater than ap.SquaredEuclideanNorm()
|
||||
if( g < 0 )
|
||||
return 0;
|
||||
|
||||
return KiROUND<double, ecoord>( ap.SquaredEuclideanNorm() - g );
|
||||
return KiROUND<double, ecoord>( g );
|
||||
}
|
||||
|
||||
|
||||
|
@ -346,11 +346,23 @@ static const std::vector<SEG_VECTOR_DISTANCE_CASE> seg_vec_dist_cases = {
|
||||
282, // sqrt(200^2 + 200^2) = 282.8, rounded to nearest
|
||||
},
|
||||
{
|
||||
"Issue 18473 (distance negative)",
|
||||
"Issue 18473 (inside hit with rounding error)",
|
||||
{ { 187360000, 42510000 }, { 105796472, 42510000 } },
|
||||
{ 106645000, 42510000 },
|
||||
std::numeric_limits<std::int32_t>::max(), // maximal distance
|
||||
}
|
||||
0,
|
||||
},
|
||||
{
|
||||
"Straight line x distance",
|
||||
{ { 187360000, 42510000 }, { 105796472, 42510000 } },
|
||||
{ 197360000, 42510000 },
|
||||
10000000,
|
||||
},
|
||||
{
|
||||
"Straight line -x distance",
|
||||
{ { 187360000, 42510000 }, { 105796472, 42510000 } },
|
||||
{ 104796472, 42510000 },
|
||||
1000000,
|
||||
},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user