@ -494,7 +494,7 @@ void RN_NET::AddCluster( std::shared_ptr<CN_CLUSTER> aCluster )
}
bool RN_NET : : NearestBicoloredPair ( const RN_NET & aOtherNet , VECTOR2I * aPos1 , VECTOR2I * aPos2 ) const
bool RN_NET : : NearestBicoloredPair ( RN_NET * aOtherNet , VECTOR2I & aPos1 , VECTOR2I & aPos2 ) const
{
bool rv = false ;
@ -511,32 +511,36 @@ bool RN_NET::NearestBicoloredPair( const RN_NET& aOtherNet, VECTOR2I* aPos1, VEC
{
rv = true ;
distMax_sq = dist_sq ;
* aPos1 = aTestNode1 - > Pos ( ) ;
* aPos2 = aTestNode2 - > Pos ( ) ;
aPos1 = aTestNode1 - > Pos ( ) ;
aPos2 = aTestNode2 - > Pos ( ) ;
}
} ;
std : : multiset < std : : shared_ptr < CN_ANCHOR > , CN_PTR_CMP > nodes_b ;
std : : copy_if ( m_nodes . begin ( ) , m_nodes . end ( ) , std : : inserter ( nodes_b , nodes_b . end ( ) ) ,
[ ] ( const std : : shared_ptr < CN_ANCHOR > & aVal )
{ return ! aVal - > GetNoLine ( ) ; } ) ;
/// Sweep-line algorithm to cut the number of comparisons to find the closest point
///
/// Step 1: The outer loop needs to be the subset (selected nodes) as it is a linear search
for ( const std : : shared_ptr < CN_ANCHOR > & nodeA : aOtherNet . m_nodes )
for ( const std : : shared_ptr < CN_ANCHOR > & nodeA : aOtherNet - > m_nodes )
{
if ( nodeA - > GetNoLine ( ) )
continue ;
/// Step 2: O( log n ) search to identify a close element ordered by x
/// The fwd_it iterator will move forward through the elements while
/// the rev_it iterator will move backward through the same set
auto fwd_it = m_ nodes. lower_bound ( nodeA ) ;
auto fwd_it = nodes_b . lower_bound ( nodeA ) ;
auto rev_it = std : : make_reverse_iterator ( fwd_it ) ;
for ( ; fwd_it ! = m_ nodes. end ( ) ; + + fwd_it )
for ( ; fwd_it ! = nodes_b . end ( ) ; + + fwd_it )
{
const std : : shared_ptr < CN_ANCHOR > & nodeB = * fwd_it ;
if ( nodeB - > GetNoLine ( ) )
continue ;
SEG : : ecoord distX_sq = SEG : : Square ( nodeA - > Pos ( ) . x - nodeB - > Pos ( ) . x ) ;
/// As soon as the x distance (primary sort) is larger than the smallest distance,
@ -548,13 +552,10 @@ bool RN_NET::NearestBicoloredPair( const RN_NET& aOtherNet, VECTOR2I* aPos1, VEC
}
/// Step 3: using the same starting point, check points backwards for closer points
for ( ; rev_it ! = m_ nodes. rend ( ) ; + + rev_it )
for ( ; rev_it ! = nodes_b . rend ( ) ; + + rev_it )
{
const std : : shared_ptr < CN_ANCHOR > & nodeB = * rev_it ;
if ( nodeB - > GetNoLine ( ) )
continue ;
SEG : : ecoord distX_sq = SEG : : Square ( nodeA - > Pos ( ) . x - nodeB - > Pos ( ) . x ) ;
if ( distX_sq > distMax_sq )