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,
|
bool SHAPE_ARC::Collide( const VECTOR2I& aP, int aClearance, int* aActual,
|
||||||
VECTOR2I* aLocation ) const
|
VECTOR2I* aLocation ) const
|
||||||
{
|
{
|
||||||
int minDist = aClearance + std::max( m_width / 2, 1 );
|
int minDist = aClearance + m_width / 2;
|
||||||
auto bbox = BBox( minDist );
|
auto bbox = BBox( minDist );
|
||||||
|
|
||||||
// Fast check using bounding box:
|
// Fast check using bounding box:
|
||||||
if( !bbox.Contains( aP ) )
|
if( !bbox.Contains( aP ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
VECTOR2I center = GetCenter();
|
CIRCLE fullCircle( GetCenter(), GetRadius() );
|
||||||
VECTOR2I vec = aP - center;
|
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 not a 360 degree arc, need to use arc angles to decide if point collides
|
||||||
if( m_start != m_end )
|
if( m_start != m_end )
|
||||||
{
|
{
|
||||||
bool ccw = GetCentralAngle() > ANGLE_0;
|
bool ccw = GetCentralAngle() > ANGLE_0;
|
||||||
EDA_ANGLE vecAngle( vec );
|
EDA_ANGLE angleToPt( aP - fullCircle.Center ); // Angle from center to the point
|
||||||
EDA_ANGLE rotatedVecAngle = ( vecAngle.Normalize() - GetStartAngle() ).Normalize();
|
EDA_ANGLE rotatedPtAngle = ( angleToPt.Normalize() - GetStartAngle() ).Normalize();
|
||||||
EDA_ANGLE rotatedEndAngle = ( GetEndAngle() - GetStartAngle() ).Normalize();
|
EDA_ANGLE rotatedEndAngle = ( GetEndAngle() - GetStartAngle() ).Normalize();
|
||||||
|
|
||||||
if( ( ccw && rotatedVecAngle > rotatedEndAngle )
|
if( ( ccw && rotatedPtAngle > rotatedEndAngle )
|
||||||
|| ( !ccw && rotatedVecAngle < rotatedEndAngle ) )
|
|| ( !ccw && rotatedPtAngle < rotatedEndAngle ) )
|
||||||
{
|
{
|
||||||
int distStartpt = ( aP - m_start ).EuclideanNorm();
|
int distStartpt = ( aP - m_start ).EuclideanNorm();
|
||||||
int distEndpt = ( aP - m_end ).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 = {
|
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, 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, 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 },
|
{ " 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, 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, 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, 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, { 74, 75 }, true, 5 }, // 74.246, -74.246
|
||||||
{ " 270deg, 5 cl, -45 deg, 5 pos", { { 0, 0 }, { 100, 0 }, 270.0 }, 5, { 75, -74 }, false, -1 },
|
{ " 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, 68 }, true, 5 },
|
{ " 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, -68 }, false, -1 },
|
{ " 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, { 106, 0 }, false, -1 },
|
{ " 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, 106 }, 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, { -106, 0 }, 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, -106 }, 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, 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, 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 },
|
{ " 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, 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, 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 },
|
{ " -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,
|
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 ) );
|
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)
|
int dist = -1;
|
||||||
BOOST_TEST_CONTEXT( "Test Clearance" )
|
BOOST_CHECK_EQUAL( arc.Collide( c.m_point, c.m_arc_clearance, &dist ),
|
||||||
{
|
c.m_exp_result );
|
||||||
int dist = -1;
|
BOOST_CHECK_EQUAL( dist, c.m_exp_distance );
|
||||||
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)
|
// Test by changing the width of the arc (distance should equal zero)
|
||||||
|
|
Loading…
Reference in New Issue