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:
|
case SHAPE_T::POLY:
|
||||||
if( IsFilled() )
|
if( IsFilled() )
|
||||||
{
|
|
||||||
return m_poly.Collide( VECTOR2I( aPosition ), maxdist );
|
return m_poly.Collide( VECTOR2I( aPosition ), maxdist );
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
return m_poly.CollideEdge( VECTOR2I( aPosition ), nullptr, maxdist );
|
||||||
SHAPE_POLY_SET::VERTEX_INDEX dummy;
|
|
||||||
return m_poly.CollideEdge( VECTOR2I( aPosition ), dummy, maxdist );
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
UNIMPLEMENTED_FOR( SHAPE_T_asString() );
|
UNIMPLEMENTED_FOR( SHAPE_T_asString() );
|
||||||
|
|
|
@ -1161,7 +1161,7 @@ public:
|
||||||
* @param aClosestVertex is the index of the closes vertex to \p aPoint.
|
* @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.
|
* @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;
|
int aClearance = 0 ) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1174,7 +1174,7 @@ public:
|
||||||
* @param aClosestVertex is the index of the closes vertex to \p aPoint.
|
* @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.
|
* @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;
|
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,
|
bool SHAPE_POLY_SET::CollideVertex( const VECTOR2I& aPoint,
|
||||||
SHAPE_POLY_SET::VERTEX_INDEX& aClosestVertex,
|
SHAPE_POLY_SET::VERTEX_INDEX* aClosestVertex,
|
||||||
int aClearance ) const
|
int aClearance ) const
|
||||||
{
|
{
|
||||||
// Shows whether there was a collision
|
// 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.
|
// Difference vector between each vertex and aPoint.
|
||||||
VECTOR2D delta;
|
VECTOR2D delta;
|
||||||
double distance, clearance;
|
ecoord distance_squared;
|
||||||
|
ecoord clearance_squared = SEG::Square( aClearance );
|
||||||
// Convert clearance to double for precision when comparing distances
|
|
||||||
clearance = aClearance;
|
|
||||||
|
|
||||||
for( CONST_ITERATOR iterator = CIterateWithHoles(); iterator; iterator++ )
|
for( CONST_ITERATOR iterator = CIterateWithHoles(); iterator; iterator++ )
|
||||||
{
|
{
|
||||||
|
@ -1719,18 +1717,21 @@ bool SHAPE_POLY_SET::CollideVertex( const VECTOR2I& aPoint,
|
||||||
delta = *iterator - aPoint;
|
delta = *iterator - aPoint;
|
||||||
|
|
||||||
// Compute distance
|
// Compute distance
|
||||||
distance = delta.EuclideanNorm();
|
distance_squared = delta.SquaredEuclideanNorm();
|
||||||
|
|
||||||
// Check for collisions
|
// Check for collisions
|
||||||
if( distance <= clearance )
|
if( distance_squared <= clearance_squared )
|
||||||
{
|
{
|
||||||
|
if( !aClosestVertex )
|
||||||
|
return true;
|
||||||
|
|
||||||
collision = true;
|
collision = true;
|
||||||
|
|
||||||
// Update aClearance to look for closer vertices
|
// Update clearance to look for closer vertices
|
||||||
clearance = distance;
|
clearance_squared = distance_squared;
|
||||||
|
|
||||||
// Store the indices that identify the vertex
|
// 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,
|
bool SHAPE_POLY_SET::CollideEdge( const VECTOR2I& aPoint,
|
||||||
SHAPE_POLY_SET::VERTEX_INDEX& aClosestVertex,
|
SHAPE_POLY_SET::VERTEX_INDEX* aClosestVertex,
|
||||||
int aClearance ) const
|
int aClearance ) const
|
||||||
{
|
{
|
||||||
// Shows whether there was a collision
|
// 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++ )
|
for( CONST_SEGMENT_ITERATOR iterator = CIterateSegmentsWithHoles(); iterator; iterator++ )
|
||||||
{
|
{
|
||||||
const SEG currentSegment = *iterator;
|
const SEG currentSegment = *iterator;
|
||||||
int distance = currentSegment.Distance( aPoint );
|
ecoord distance_squared = currentSegment.SquaredDistance( aPoint );
|
||||||
|
|
||||||
// Check for collisions
|
// Check for collisions
|
||||||
if( distance <= aClearance )
|
if( distance_squared <= clearance_squared )
|
||||||
{
|
{
|
||||||
|
if( !aClosestVertex )
|
||||||
|
return true;
|
||||||
|
|
||||||
collision = true;
|
collision = true;
|
||||||
|
|
||||||
// Update aClearance to look for closer edges
|
// Update clearance to look for closer edges
|
||||||
aClearance = distance;
|
clearance_squared = distance_squared;
|
||||||
|
|
||||||
// Store the indices that identify the vertex
|
// 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,
|
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 );
|
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,
|
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 );
|
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
|
bool ZONE::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
|
||||||
{
|
{
|
||||||
// Calculate bounding box for zone
|
// 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; }
|
int GetLocalFlags() const { return m_localFlgs; }
|
||||||
void SetLocalFlags( int aFlags ) { m_localFlgs = aFlags; }
|
void SetLocalFlags( int aFlags ) { m_localFlgs = aFlags; }
|
||||||
|
|
||||||
|
@ -423,43 +420,25 @@ public:
|
||||||
*
|
*
|
||||||
* @param refPos is the VECTOR2I to test.
|
* @param refPos is the VECTOR2I to test.
|
||||||
* @param aAccuracy increase the item bounding box by this amount.
|
* @param aAccuracy increase the item bounding box by this amount.
|
||||||
* @param aCornerHit [out] is the index of the closest vertex found, useless when return
|
* @param aCornerHit [out, optional] is the index of the closest vertex found when return
|
||||||
* value is false.
|
* value is true
|
||||||
* @return true if some corner was found to be closer to refPos than aClearance; false
|
* @return true if some corner was found to be closer to refPos than aClearance; false
|
||||||
* otherwise.
|
* otherwise.
|
||||||
*/
|
*/
|
||||||
bool HitTestForCorner( const VECTOR2I& refPos, int aAccuracy,
|
bool HitTestForCorner( const VECTOR2I& refPos, int aAccuracy,
|
||||||
SHAPE_POLY_SET::VERTEX_INDEX& aCornerHit ) const;
|
SHAPE_POLY_SET::VERTEX_INDEX* aCornerHit = nullptr ) 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;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test if the given VECTOR2I is near a segment defined by 2 corners.
|
* Test if the given VECTOR2I is near a segment defined by 2 corners.
|
||||||
*
|
*
|
||||||
* @param refPos is the VECTOR2I to test.
|
* @param refPos is the VECTOR2I to test.
|
||||||
* @param aAccuracy increase the item bounding box by this amount.
|
* @param aAccuracy increase the item bounding box by this amount.
|
||||||
* @param aCornerHit [out] is the index of the closest vertex found, useless when return
|
* @param aCornerHit [out, optional] is the index of the closest vertex found when return
|
||||||
* value is false.
|
* value is true.
|
||||||
* @return true if some edge was found to be closer to refPos than aClearance.
|
* @return true if some edge was found to be closer to refPos than aClearance.
|
||||||
*/
|
*/
|
||||||
bool HitTestForEdge( const VECTOR2I& refPos, int aAccuracy,
|
bool HitTestForEdge( const VECTOR2I& refPos, int aAccuracy,
|
||||||
SHAPE_POLY_SET::VERTEX_INDEX& aCornerHit ) 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.
|
|
||||||
* @return true if some edge was found to be closer to refPos than aClearance.
|
|
||||||
*/
|
|
||||||
bool HitTestForEdge( const VECTOR2I& refPos, int aAccuracy ) const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copydoc BOARD_ITEM::HitTest(const EDA_RECT& aRect,
|
* @copydoc BOARD_ITEM::HitTest(const EDA_RECT& aRect,
|
||||||
|
|
|
@ -214,14 +214,12 @@ BOOST_AUTO_TEST_CASE( Collide )
|
||||||
*/
|
*/
|
||||||
BOOST_AUTO_TEST_CASE( CollideVertex )
|
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
|
// Check that the set collides with the colliding points
|
||||||
for( const VECTOR2I& point : common.holeyPoints )
|
for( const VECTOR2I& point : common.holeyPoints )
|
||||||
{
|
{
|
||||||
BOOST_CHECK_MESSAGE( common.holeyPolySet.CollideVertex( point, cornerHit, 0 ), " Point "
|
BOOST_CHECK_MESSAGE( common.holeyPolySet.CollideVertex( point, nullptr, 0 ),
|
||||||
<< point.x << ", " << point.y << " does not collide with holeyPolySet polygon" );
|
" 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 )
|
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
|
// Check that the set collides with the colliding points
|
||||||
for( const VECTOR2I& point : common.holeyPoints )
|
for( const VECTOR2I& point : common.holeyPoints )
|
||||||
{
|
BOOST_CHECK( common.holeyPolySet.CollideVertex( point + VECTOR2I( 1, 1 ), nullptr, 2 ) );
|
||||||
BOOST_CHECK( common.holeyPolySet.CollideVertex( point + VECTOR2I( 1, 1 ), cornerHit, 2 ) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue