Add true arc-to-polyline collisions
This commit is contained in:
parent
dd65ce9523
commit
eaf8eb284a
|
@ -534,14 +534,53 @@ static inline bool Collide( const SHAPE_ARC& aA, const SHAPE_LINE_CHAIN_BASE& aB
|
||||||
aA.Type(),
|
aA.Type(),
|
||||||
aB.Type() ) );
|
aB.Type() ) );
|
||||||
|
|
||||||
const SHAPE_LINE_CHAIN lc = aA.ConvertToPolyline();
|
int closest_dist = INT_MAX;
|
||||||
|
VECTOR2I nearest;
|
||||||
|
|
||||||
bool rv = Collide( lc, aB, aClearance + aA.GetWidth() / 2, aActual, aLocation, aMTV );
|
if( aB.IsClosed() && aB.PointInside( aA.GetP0() ) )
|
||||||
|
{
|
||||||
|
closest_dist = 0;
|
||||||
|
nearest = aA.GetP0();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for( size_t i = 0; i < aB.GetSegmentCount(); i++ )
|
||||||
|
{
|
||||||
|
int collision_dist = 0;
|
||||||
|
VECTOR2I pn;
|
||||||
|
|
||||||
if( rv && aActual )
|
if( aA.Collide( aB.GetSegment( i ), aClearance,
|
||||||
*aActual = std::max( 0, *aActual - aA.GetWidth() / 2 );
|
aActual || aLocation ? &collision_dist : nullptr,
|
||||||
|
aLocation ? &pn : nullptr ) )
|
||||||
|
{
|
||||||
|
if( collision_dist < closest_dist )
|
||||||
|
{
|
||||||
|
nearest = pn;
|
||||||
|
closest_dist = collision_dist;
|
||||||
|
}
|
||||||
|
|
||||||
return rv;
|
if( closest_dist == 0 )
|
||||||
|
break;
|
||||||
|
|
||||||
|
// If we're not looking for aActual then any collision will do
|
||||||
|
if( !aActual )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( closest_dist == 0 || closest_dist < aClearance )
|
||||||
|
{
|
||||||
|
if( aLocation )
|
||||||
|
*aLocation = nearest;
|
||||||
|
|
||||||
|
if( aActual )
|
||||||
|
*aActual = closest_dist;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -761,10 +761,11 @@ BOOST_AUTO_TEST_CASE( CollideArcToPolygonApproximation )
|
||||||
// Create a polyset approximation from the arc - error outside (simulating the zone filler)
|
// Create a polyset approximation from the arc - error outside (simulating the zone filler)
|
||||||
SHAPE_POLY_SET arcBuffer;
|
SHAPE_POLY_SET arcBuffer;
|
||||||
int clearance = ( arc.GetWidth() * 3 ) / 2;
|
int clearance = ( arc.GetWidth() * 3 ) / 2;
|
||||||
|
int polygonApproximationError = SHAPE_ARC::DefaultAccuracyForPCB();
|
||||||
|
|
||||||
TransformArcToPolygon( arcBuffer, wxPoint( arc.GetP0() ), wxPoint( arc.GetArcMid() ),
|
TransformArcToPolygon( arcBuffer, wxPoint( arc.GetP0() ), wxPoint( arc.GetArcMid() ),
|
||||||
wxPoint( arc.GetP1() ), arc.GetWidth() + 2 * clearance,
|
wxPoint( arc.GetP1() ), arc.GetWidth() + 2 * clearance,
|
||||||
SHAPE_ARC::DefaultAccuracyForPCB(), ERROR_OUTSIDE );
|
polygonApproximationError, ERROR_OUTSIDE );
|
||||||
|
|
||||||
BOOST_REQUIRE_EQUAL( arcBuffer.OutlineCount(), 1 );
|
BOOST_REQUIRE_EQUAL( arcBuffer.OutlineCount(), 1 );
|
||||||
BOOST_CHECK_EQUAL( arcBuffer.HoleCount( 0 ), 0 );
|
BOOST_CHECK_EQUAL( arcBuffer.HoleCount( 0 ), 0 );
|
||||||
|
@ -793,7 +794,7 @@ BOOST_AUTO_TEST_CASE( CollideArcToPolygonApproximation )
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL( zoneFill.Collide( &arc, clearance * 2, &actual, &location ), true );
|
BOOST_CHECK_EQUAL( zoneFill.Collide( &arc, clearance * 2, &actual, &location ), true );
|
||||||
|
|
||||||
BOOST_CHECK( KI_TEST::IsWithin( actual, clearance, tol ) );
|
BOOST_CHECK( KI_TEST::IsWithin( actual, clearance, polygonApproximationError ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue