Performance optimizations.

This commit is contained in:
Jeff Young 2021-06-01 22:07:52 +01:00
parent d12e5d824e
commit 46d746c9da
3 changed files with 49 additions and 27 deletions

View File

@ -199,6 +199,8 @@ public:
OPT_VECTOR2I Intersect( const SEG& aSeg, bool aIgnoreEndpoints = false,
bool aLines = false ) const;
bool Intersects( const SEG& aSeg ) const;
/**
* Compute the intersection point of lines passing through ends of (this) and \a aSeg.
*
@ -396,6 +398,9 @@ public:
private:
bool ccw( const VECTOR2I& aA, const VECTOR2I& aB, const VECTOR2I &aC ) const;
bool intersects( const SEG& aSeg, bool aIgnoreEndpoints = false, bool aLines = false,
VECTOR2I* aPt = nullptr ) const;
private:
///< index withing the parent shape (used when m_is_local == false)
int m_index;

View File

@ -38,8 +38,7 @@ int sgn( T aVal )
SEG::ecoord SEG::SquaredDistance( const SEG& aSeg ) const
{
// fixme: rather inefficient....
if( Intersect( aSeg ) )
if( Intersects( aSeg ) )
return 0;
const VECTOR2I pts[4] =
@ -53,9 +52,7 @@ SEG::ecoord SEG::SquaredDistance( const SEG& aSeg ) const
ecoord m = VECTOR2I::ECOORD_MAX;
for( int i = 0; i < 4; i++ )
{
m = std::min( m, pts[i].SquaredEuclideanNorm() );
}
return m;
}
@ -116,7 +113,7 @@ const VECTOR2I SEG::NearestPoint( const SEG& aSeg ) const
}
OPT_VECTOR2I SEG::Intersect( const SEG& aSeg, bool aIgnoreEndpoints, bool aLines ) const
bool SEG::intersects( const SEG& aSeg, bool aIgnoreEndpoints, bool aLines, VECTOR2I* aPt ) const
{
const VECTOR2I e( B - A );
const VECTOR2I f( aSeg.B - aSeg.A );
@ -127,21 +124,41 @@ OPT_VECTOR2I SEG::Intersect( const SEG& aSeg, bool aIgnoreEndpoints, bool aLines
ecoord q = e.Cross( ac );
if( d == 0 )
return OPT_VECTOR2I();
return false;
if( !aLines && d > 0 && ( q < 0 || q > d || p < 0 || p > d ) )
return OPT_VECTOR2I();
return false;
if( !aLines && d < 0 && ( q < d || p < d || p > 0 || q > 0 ) )
return OPT_VECTOR2I();
return false;
if( !aLines && aIgnoreEndpoints && ( q == 0 || q == d ) && ( p == 0 || p == d ) )
return OPT_VECTOR2I();
return false;
VECTOR2I ip( aSeg.A.x + rescale( q, (ecoord) f.x, d ),
if( aPt )
{
*aPt = VECTOR2I( aSeg.A.x + rescale( q, (ecoord) f.x, d ),
aSeg.A.y + rescale( q, (ecoord) f.y, d ) );
}
return true;
}
bool SEG::Intersects( const SEG& aSeg ) const
{
return intersects( aSeg );
}
OPT_VECTOR2I SEG::Intersect( const SEG& aSeg, bool aIgnoreEndpoints, bool aLines ) const
{
VECTOR2I ip;
if( intersects( aSeg, aIgnoreEndpoints, aLines, &ip ) )
return ip;
else
return OPT_VECTOR2I();
}
@ -203,5 +220,5 @@ bool SEG::Collide( const SEG& aSeg, int aClearance, int* aActual ) const
bool SEG::Contains( const VECTOR2I& aP ) const
{
return Distance( aP ) <= 1; // 1 * 1 to be pedantic
return Distance( aP ) <= 1;
}

View File

@ -173,7 +173,7 @@ bool SHAPE_LINE_CHAIN_BASE::Collide( const SEG& aSeg, int aClearance, int* aActu
for( size_t i = 0; i < GetSegmentCount(); i++ )
{
const SEG& s = GetSegment( i );
SEG::ecoord dist_sq =s.SquaredDistance( aSeg );
SEG::ecoord dist_sq = s.SquaredDistance( aSeg );
if( dist_sq < closest_dist_sq )
{