Fix rounding errors in SHAPE_ARC::Collide + fix qa tests
Use CIRCLE::NearestPoint to ensure consistency
This commit is contained in:
parent
3b796265a0
commit
4defc946ef
|
@ -369,28 +369,28 @@ bool SHAPE_ARC::IsClockwise() const
|
|||
bool SHAPE_ARC::Collide( const VECTOR2I& aP, int aClearance, int* aActual,
|
||||
VECTOR2I* aLocation ) const
|
||||
{
|
||||
int minDist = aClearance + std::max( m_width / 2, 1 );
|
||||
int minDist = aClearance + m_width / 2;
|
||||
auto bbox = BBox( minDist );
|
||||
|
||||
// Fast check using bounding box:
|
||||
if( !bbox.Contains( aP ) )
|
||||
return false;
|
||||
|
||||
VECTOR2I center = GetCenter();
|
||||
VECTOR2I vec = aP - center;
|
||||
CIRCLE fullCircle( GetCenter(), GetRadius() );
|
||||
VECTOR2I nearestPt = fullCircle.NearestPoint( aP );
|
||||
|
||||
int dist = abs( vec.EuclideanNorm() - GetRadius() );
|
||||
int dist = ( nearestPt - aP ).EuclideanNorm();
|
||||
|
||||
// If not a 360 degree arc, need to use arc angles to decide if point collides
|
||||
if( m_start != m_end )
|
||||
{
|
||||
bool ccw = GetCentralAngle() > ANGLE_0;
|
||||
EDA_ANGLE vecAngle( vec );
|
||||
EDA_ANGLE rotatedVecAngle = ( vecAngle.Normalize() - GetStartAngle() ).Normalize();
|
||||
EDA_ANGLE angleToPt( aP - fullCircle.Center ); // Angle from center to the point
|
||||
EDA_ANGLE rotatedPtAngle = ( angleToPt.Normalize() - GetStartAngle() ).Normalize();
|
||||
EDA_ANGLE rotatedEndAngle = ( GetEndAngle() - GetStartAngle() ).Normalize();
|
||||
|
||||
if( ( ccw && rotatedVecAngle > rotatedEndAngle )
|
||||
|| ( !ccw && rotatedVecAngle < rotatedEndAngle ) )
|
||||
if( ( ccw && rotatedPtAngle > rotatedEndAngle )
|
||||
|| ( !ccw && rotatedPtAngle < rotatedEndAngle ) )
|
||||
{
|
||||
int distStartpt = ( aP - m_start ).EuclideanNorm();
|
||||
int distEndpt = ( aP - m_end ).EuclideanNorm();
|
||||
|
|
|
@ -558,7 +558,7 @@ struct ARC_PT_COLLIDE_CASE
|
|||
|
||||
|
||||
static const std::vector<ARC_PT_COLLIDE_CASE> arc_pt_collide_cases = {
|
||||
{ " 270deg, 0 cl, 0 deg ", { { 0, 0 }, { 100, 0 }, 270.0 }, 0, { 100, 0 }, true, 0 },
|
||||
{ " 270deg, 0 cl, 0 deg ", { { 0, 0 }, { 100, 0 }, 270.0 }, 0, { 100, 0 }, true, 0 },
|
||||
{ " 270deg, 0 cl, 90 deg ", { { 0, 0 }, { 100, 0 }, 270.0 }, 0, { 0, 100 }, true, 0 },
|
||||
{ " 270deg, 0 cl, 180 deg ", { { 0, 0 }, { 100, 0 }, 270.0 }, 0, { -100, 0 }, true, 0 },
|
||||
{ " 270deg, 0 cl, 270 deg ", { { 0, 0 }, { 100, 0 }, 270.0 }, 0, { 0, -100 }, true, 0 },
|
||||
|
@ -579,14 +579,14 @@ static const std::vector<ARC_PT_COLLIDE_CASE> arc_pt_collide_cases = {
|
|||
{ " 270deg, 5 cl, 90 deg, 5 neg", { { 0, 0 }, { 100, 0 }, 270.0 }, 5, { 0, 105 }, true, 5 },
|
||||
{ " 270deg, 5 cl, 180 deg, 5 neg", { { 0, 0 }, { 100, 0 }, 270.0 }, 5, { -105, 0 }, true, 5 },
|
||||
{ " 270deg, 5 cl, 270 deg, 5 neg", { { 0, 0 }, { 100, 0 }, 270.0 }, 5, { 0, -105 }, true, 5 },
|
||||
{ " 270deg, 5 cl, 45 deg, 5 pos", { { 0, 0 }, { 100, 0 }, 270.0 }, 5, { 75, 74 }, true, 5 },
|
||||
{ " 270deg, 5 cl, -45 deg, 5 pos", { { 0, 0 }, { 100, 0 }, 270.0 }, 5, { 75, -74 }, false, -1 },
|
||||
{ " 270deg, 5 cl, 45 deg, 5 neg", { { 0, 0 }, { 100, 0 }, 270.0 }, 5, { 67, 68 }, true, 5 },
|
||||
{ " 270deg, 5 cl, -45 deg, 5 neg", { { 0, 0 }, { 100, 0 }, 270.0 }, 5, { 67, -68 }, false, -1 },
|
||||
{ " 270deg, 4 cl, 0 deg pos", { { 0, 0 }, { 100, 0 }, 270.0 }, 4, { 106, 0 }, false, -1 },
|
||||
{ " 270deg, 4 cl, 90 deg pos", { { 0, 0 }, { 100, 0 }, 270.0 }, 4, { 0, 106 }, false, -1 },
|
||||
{ " 270deg, 4 cl, 180 deg pos", { { 0, 0 }, { 100, 0 }, 270.0 }, 4, { -106, 0 }, false, -1 },
|
||||
{ " 270deg, 4 cl, 270 deg pos", { { 0, 0 }, { 100, 0 }, 270.0 }, 4, { 0, -106 }, false, -1 },
|
||||
{ " 270deg, 5 cl, 45 deg, 5 pos", { { 0, 0 }, { 100, 0 }, 270.0 }, 5, { 74, 75 }, true, 5 }, // 74.246, -74.246
|
||||
{ " 270deg, 5 cl, -45 deg, 5 pos", { { 0, 0 }, { 100, 0 }, 270.0 }, 5, { 74, -75 }, false, -1 }, //74.246, -74.246
|
||||
{ " 270deg, 5 cl, 45 deg, 5 neg", { { 0, 0 }, { 100, 0 }, 270.0 }, 5, { 67, 67 }, true, 5 }, // 67.17, 67.17
|
||||
{ " 270deg, 5 cl, -45 deg, 5 neg", { { 0, 0 }, { 100, 0 }, 270.0 }, 5, { 67, -67 }, false, -1 }, // 67.17, -67.17
|
||||
{ " 270deg, 4 cl, 0 deg pos", { { 0, 0 }, { 100, 0 }, 270.0 }, 4, { 105, 0 }, false, -1 },
|
||||
{ " 270deg, 4 cl, 90 deg pos", { { 0, 0 }, { 100, 0 }, 270.0 }, 4, { 0, 105 }, false, -1 },
|
||||
{ " 270deg, 4 cl, 180 deg pos", { { 0, 0 }, { 100, 0 }, 270.0 }, 4, { -105, 0 }, false, -1 },
|
||||
{ " 270deg, 4 cl, 270 deg pos", { { 0, 0 }, { 100, 0 }, 270.0 }, 4, { 0, -105 }, false, -1 },
|
||||
{ " 90deg, 0 cl, 0 deg ", { { 0, 0 }, { 71, -71 }, 90.0 }, 0, { 71, -71 }, true, 0 },
|
||||
{ " 90deg, 0 cl, 45 deg ", { { 0, 0 }, { 71, -71 }, 90.0 }, 0, { 100, 0 }, true, 0 },
|
||||
{ " 90deg, 0 cl, 90 deg ", { { 0, 0 }, { 71, -71 }, 90.0 }, 0, { 71, 71 }, true, 0 },
|
||||
|
@ -597,6 +597,12 @@ static const std::vector<ARC_PT_COLLIDE_CASE> arc_pt_collide_cases = {
|
|||
{ " -90deg, 0 cl, 90 deg ", { { 0, 0 }, { 71, 71 }, -90.0 }, 0, { 71, 71 }, true, 0 },
|
||||
{ " -90deg, 0 cl, 135 deg ", { { 0, 0 }, { 71, 71 }, -90.0 }, 0, { 0, -100 }, false, -1 },
|
||||
{ " -90deg, 0 cl, -45 deg ", { { 0, 0 }, { 71, 71 }, -90.0 }, 0, { 0, 100 }, false, -1 },
|
||||
{ "issue 11358",
|
||||
{ { 119888000, 60452000 }, { 120904000, 60452000 }, 360.0 },
|
||||
0,
|
||||
{ 120395500, 59571830 },
|
||||
true,
|
||||
0 },
|
||||
};
|
||||
|
||||
|
||||
|
@ -609,16 +615,13 @@ BOOST_AUTO_TEST_CASE( CollidePt )
|
|||
SHAPE_ARC arc( c.m_geom.m_center_point, c.m_geom.m_start_point,
|
||||
EDA_ANGLE( c.m_geom.m_center_angle, DEGREES_T ) );
|
||||
|
||||
if( c.m_arc_clearance > 0 )
|
||||
// Test a zero width arc (distance should equal the clearance)
|
||||
BOOST_TEST_CONTEXT( "Test Clearance" )
|
||||
{
|
||||
// Test a zero width arc (distance should equal the clearance)
|
||||
BOOST_TEST_CONTEXT( "Test Clearance" )
|
||||
{
|
||||
int dist = -1;
|
||||
BOOST_CHECK_EQUAL( arc.Collide( c.m_point, c.m_arc_clearance, &dist ),
|
||||
c.m_exp_result );
|
||||
BOOST_CHECK_EQUAL( dist, c.m_exp_distance );
|
||||
}
|
||||
int dist = -1;
|
||||
BOOST_CHECK_EQUAL( arc.Collide( c.m_point, c.m_arc_clearance, &dist ),
|
||||
c.m_exp_result );
|
||||
BOOST_CHECK_EQUAL( dist, c.m_exp_distance );
|
||||
}
|
||||
|
||||
// Test by changing the width of the arc (distance should equal zero)
|
||||
|
|
Loading…
Reference in New Issue