Performance: avoid sqrt at all costs.
This commit is contained in:
parent
ded4840130
commit
b727bfc16d
|
@ -795,14 +795,9 @@ bool EDA_SHAPE::hitTest( const VECTOR2I& aPosition, int aAccuracy ) const
|
|||
|
||||
case SHAPE_T::POLY:
|
||||
if( IsFilled() )
|
||||
{
|
||||
return m_poly.Collide( VECTOR2I( aPosition ), maxdist );
|
||||
}
|
||||
else
|
||||
{
|
||||
SHAPE_POLY_SET::VERTEX_INDEX dummy;
|
||||
return m_poly.CollideEdge( VECTOR2I( aPosition ), dummy, maxdist );
|
||||
}
|
||||
return m_poly.CollideEdge( VECTOR2I( aPosition ), nullptr, maxdist );
|
||||
|
||||
default:
|
||||
UNIMPLEMENTED_FOR( SHAPE_T_asString() );
|
||||
|
|
|
@ -1161,7 +1161,7 @@ public:
|
|||
* @param aClosestVertex is the index of the closes vertex to \p aPoint.
|
||||
* @return bool - true if there is a collision, false in any other case.
|
||||
*/
|
||||
bool CollideVertex( const VECTOR2I& aPoint, VERTEX_INDEX& aClosestVertex,
|
||||
bool CollideVertex( const VECTOR2I& aPoint, VERTEX_INDEX* aClosestVertex = nullptr,
|
||||
int aClearance = 0 ) const;
|
||||
|
||||
/**
|
||||
|
@ -1174,7 +1174,7 @@ public:
|
|||
* @param aClosestVertex is the index of the closes vertex to \p aPoint.
|
||||
* @return bool - true if there is a collision, false in any other case.
|
||||
*/
|
||||
bool CollideEdge( const VECTOR2I& aPoint, VERTEX_INDEX& aClosestVertex,
|
||||
bool CollideEdge( const VECTOR2I& aPoint, VERTEX_INDEX* aClosestVertex = nullptr,
|
||||
int aClearance = 0 ) const;
|
||||
|
||||
/**
|
||||
|
|
|
@ -1700,7 +1700,7 @@ void SHAPE_POLY_SET::Append( const VECTOR2I& aP, int aOutline, int aHole )
|
|||
|
||||
|
||||
bool SHAPE_POLY_SET::CollideVertex( const VECTOR2I& aPoint,
|
||||
SHAPE_POLY_SET::VERTEX_INDEX& aClosestVertex,
|
||||
SHAPE_POLY_SET::VERTEX_INDEX* aClosestVertex,
|
||||
int aClearance ) const
|
||||
{
|
||||
// Shows whether there was a collision
|
||||
|
@ -1708,10 +1708,8 @@ bool SHAPE_POLY_SET::CollideVertex( const VECTOR2I& aPoint,
|
|||
|
||||
// Difference vector between each vertex and aPoint.
|
||||
VECTOR2D delta;
|
||||
double distance, clearance;
|
||||
|
||||
// Convert clearance to double for precision when comparing distances
|
||||
clearance = aClearance;
|
||||
ecoord distance_squared;
|
||||
ecoord clearance_squared = SEG::Square( aClearance );
|
||||
|
||||
for( CONST_ITERATOR iterator = CIterateWithHoles(); iterator; iterator++ )
|
||||
{
|
||||
|
@ -1719,18 +1717,21 @@ bool SHAPE_POLY_SET::CollideVertex( const VECTOR2I& aPoint,
|
|||
delta = *iterator - aPoint;
|
||||
|
||||
// Compute distance
|
||||
distance = delta.EuclideanNorm();
|
||||
distance_squared = delta.SquaredEuclideanNorm();
|
||||
|
||||
// Check for collisions
|
||||
if( distance <= clearance )
|
||||
if( distance_squared <= clearance_squared )
|
||||
{
|
||||
if( !aClosestVertex )
|
||||
return true;
|
||||
|
||||
collision = true;
|
||||
|
||||
// Update aClearance to look for closer vertices
|
||||
clearance = distance;
|
||||
// Update clearance to look for closer vertices
|
||||
clearance_squared = distance_squared;
|
||||
|
||||
// Store the indices that identify the vertex
|
||||
aClosestVertex = iterator.GetIndex();
|
||||
*aClosestVertex = iterator.GetIndex();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1739,27 +1740,31 @@ bool SHAPE_POLY_SET::CollideVertex( const VECTOR2I& aPoint,
|
|||
|
||||
|
||||
bool SHAPE_POLY_SET::CollideEdge( const VECTOR2I& aPoint,
|
||||
SHAPE_POLY_SET::VERTEX_INDEX& aClosestVertex,
|
||||
SHAPE_POLY_SET::VERTEX_INDEX* aClosestVertex,
|
||||
int aClearance ) const
|
||||
{
|
||||
// Shows whether there was a collision
|
||||
bool collision = false;
|
||||
bool collision = false;
|
||||
ecoord clearance_squared = SEG::Square( aClearance );
|
||||
|
||||
for( CONST_SEGMENT_ITERATOR iterator = CIterateSegmentsWithHoles(); iterator; iterator++ )
|
||||
{
|
||||
const SEG currentSegment = *iterator;
|
||||
int distance = currentSegment.Distance( aPoint );
|
||||
ecoord distance_squared = currentSegment.SquaredDistance( aPoint );
|
||||
|
||||
// Check for collisions
|
||||
if( distance <= aClearance )
|
||||
if( distance_squared <= clearance_squared )
|
||||
{
|
||||
if( !aClosestVertex )
|
||||
return true;
|
||||
|
||||
collision = true;
|
||||
|
||||
// Update aClearance to look for closer edges
|
||||
aClearance = distance;
|
||||
// Update clearance to look for closer edges
|
||||
clearance_squared = distance_squared;
|
||||
|
||||
// Store the indices that identify the vertex
|
||||
aClosestVertex = iterator.GetIndex();
|
||||
*aClosestVertex = iterator.GetIndex();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -375,49 +375,20 @@ bool ZONE::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
|
|||
}
|
||||
|
||||
|
||||
void ZONE::SetSelectedCorner( const VECTOR2I& aPosition, int aAccuracy )
|
||||
{
|
||||
SHAPE_POLY_SET::VERTEX_INDEX corner;
|
||||
|
||||
// If there is some corner to be selected, assign it to m_CornerSelection
|
||||
if( HitTestForCorner( aPosition, aAccuracy * 2, corner )
|
||||
|| HitTestForEdge( aPosition, aAccuracy, corner ) )
|
||||
{
|
||||
if( m_CornerSelection == nullptr )
|
||||
m_CornerSelection = new SHAPE_POLY_SET::VERTEX_INDEX;
|
||||
|
||||
*m_CornerSelection = corner;
|
||||
}
|
||||
}
|
||||
|
||||
bool ZONE::HitTestForCorner( const VECTOR2I& refPos, int aAccuracy,
|
||||
SHAPE_POLY_SET::VERTEX_INDEX& aCornerHit ) const
|
||||
SHAPE_POLY_SET::VERTEX_INDEX* aCornerHit ) const
|
||||
{
|
||||
return m_Poly->CollideVertex( VECTOR2I( refPos ), aCornerHit, aAccuracy );
|
||||
}
|
||||
|
||||
|
||||
bool ZONE::HitTestForCorner( const VECTOR2I& refPos, int aAccuracy ) const
|
||||
{
|
||||
SHAPE_POLY_SET::VERTEX_INDEX dummy;
|
||||
return HitTestForCorner( refPos, aAccuracy, dummy );
|
||||
}
|
||||
|
||||
|
||||
bool ZONE::HitTestForEdge( const VECTOR2I& refPos, int aAccuracy,
|
||||
SHAPE_POLY_SET::VERTEX_INDEX& aCornerHit ) const
|
||||
SHAPE_POLY_SET::VERTEX_INDEX* aCornerHit ) const
|
||||
{
|
||||
return m_Poly->CollideEdge( VECTOR2I( refPos ), aCornerHit, aAccuracy );
|
||||
}
|
||||
|
||||
|
||||
bool ZONE::HitTestForEdge( const VECTOR2I& refPos, int aAccuracy ) const
|
||||
{
|
||||
SHAPE_POLY_SET::VERTEX_INDEX dummy;
|
||||
return HitTestForEdge( refPos, aAccuracy, dummy );
|
||||
}
|
||||
|
||||
|
||||
bool ZONE::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
|
||||
{
|
||||
// Calculate bounding box for zone
|
||||
|
|
|
@ -321,9 +321,6 @@ public:
|
|||
}
|
||||
|
||||
///
|
||||
// Like HitTest but selects the current corner to be operated on
|
||||
void SetSelectedCorner( const VECTOR2I& aPosition, int aAccuracy );
|
||||
|
||||
int GetLocalFlags() const { return m_localFlgs; }
|
||||
void SetLocalFlags( int aFlags ) { m_localFlgs = aFlags; }
|
||||
|
||||
|
@ -423,43 +420,25 @@ public:
|
|||
*
|
||||
* @param refPos is the VECTOR2I to test.
|
||||
* @param aAccuracy increase the item bounding box by this amount.
|
||||
* @param aCornerHit [out] is the index of the closest vertex found, useless when return
|
||||
* value is false.
|
||||
* @param aCornerHit [out, optional] is the index of the closest vertex found when return
|
||||
* value is true
|
||||
* @return true if some corner was found to be closer to refPos than aClearance; false
|
||||
* otherwise.
|
||||
*/
|
||||
bool HitTestForCorner( const VECTOR2I& refPos, int aAccuracy,
|
||||
SHAPE_POLY_SET::VERTEX_INDEX& aCornerHit ) const;
|
||||
|
||||
/**
|
||||
* Test if the given VECTOR2I is near a corner.
|
||||
* @param refPos is the VECTOR2I to test.
|
||||
* @param aAccuracy increase the item bounding box by this amount.
|
||||
* @return true if some corner was found to be closer to refPos than aClearance; false
|
||||
* otherwise.
|
||||
*/
|
||||
bool HitTestForCorner( const VECTOR2I& refPos, int aAccuracy ) const;
|
||||
SHAPE_POLY_SET::VERTEX_INDEX* aCornerHit = nullptr ) const;
|
||||
|
||||
/**
|
||||
* Test if the given VECTOR2I is near a segment defined by 2 corners.
|
||||
*
|
||||
* @param refPos is the VECTOR2I to test.
|
||||
* @param aAccuracy increase the item bounding box by this amount.
|
||||
* @param aCornerHit [out] is the index of the closest vertex found, useless when return
|
||||
* value is false.
|
||||
* @param aCornerHit [out, optional] is the index of the closest vertex found when return
|
||||
* value is true.
|
||||
* @return true if some edge was found to be closer to refPos than aClearance.
|
||||
*/
|
||||
bool HitTestForEdge( const VECTOR2I& refPos, int aAccuracy,
|
||||
SHAPE_POLY_SET::VERTEX_INDEX& aCornerHit ) const;
|
||||
|
||||
/**
|
||||
* Test if the given VECTOR2I is near a segment defined by 2 corners.
|
||||
*
|
||||
* @param refPos is the VECTOR2I to test.
|
||||
* @param aAccuracy increase the item bounding box by this amount.
|
||||
* @return true if some edge was found to be closer to refPos than aClearance.
|
||||
*/
|
||||
bool HitTestForEdge( const VECTOR2I& refPos, int aAccuracy ) const;
|
||||
SHAPE_POLY_SET::VERTEX_INDEX* aCornerHit = nullptr ) const;
|
||||
|
||||
/**
|
||||
* @copydoc BOARD_ITEM::HitTest(const EDA_RECT& aRect,
|
||||
|
|
|
@ -214,14 +214,12 @@ BOOST_AUTO_TEST_CASE( Collide )
|
|||
*/
|
||||
BOOST_AUTO_TEST_CASE( CollideVertex )
|
||||
{
|
||||
// Variable to store the index of the corner hit
|
||||
SHAPE_POLY_SET::VERTEX_INDEX cornerHit;
|
||||
|
||||
// Check that the set collides with the colliding points
|
||||
for( const VECTOR2I& point : common.holeyPoints )
|
||||
{
|
||||
BOOST_CHECK_MESSAGE( common.holeyPolySet.CollideVertex( point, cornerHit, 0 ), " Point "
|
||||
<< point.x << ", " << point.y << " does not collide with holeyPolySet polygon" );
|
||||
BOOST_CHECK_MESSAGE( common.holeyPolySet.CollideVertex( point, nullptr, 0 ),
|
||||
" Point " << point.x << ", " << point.y <<
|
||||
" does not collide with holeyPolySet polygon" );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -231,14 +229,9 @@ BOOST_AUTO_TEST_CASE( CollideVertex )
|
|||
*/
|
||||
BOOST_AUTO_TEST_CASE( CollideVertexWithClearance )
|
||||
{
|
||||
// Variable to store the index of the corner hit
|
||||
SHAPE_POLY_SET::VERTEX_INDEX cornerHit;
|
||||
|
||||
// Check that the set collides with the colliding points
|
||||
for( const VECTOR2I& point : common.holeyPoints )
|
||||
{
|
||||
BOOST_CHECK( common.holeyPolySet.CollideVertex( point + VECTOR2I( 1, 1 ), cornerHit, 2 ) );
|
||||
}
|
||||
BOOST_CHECK( common.holeyPolySet.CollideVertex( point + VECTOR2I( 1, 1 ), nullptr, 2 ) );
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue