Move SHAPE_ARC to EDA_ANGLE.

This commit is contained in:
Jeff Young 2022-01-15 12:52:20 +00:00
parent d4ee74a832
commit 1539fa5af2
11 changed files with 96 additions and 119 deletions

View File

@ -829,22 +829,13 @@ void GERBER_PLOTTER::Arc( const VECTOR2I& aCenter, double aStAngle, double aEndA
}
void GERBER_PLOTTER::Arc( const SHAPE_ARC& aArc )
{
SetCurrentLineWidth( aArc.GetWidth() );
// aFill is not used here.
plotArc( aArc, false );
}
void GERBER_PLOTTER::plotArc( const SHAPE_ARC& aArc, bool aPlotInRegion )
{
VECTOR2I start( aArc.GetP0() );
VECTOR2I end( aArc.GetP1() );
VECTOR2I center( aArc.GetCenter() );
double start_angle = aArc.GetStartAngle();
double end_angle = aArc.GetEndAngle();
VECTOR2I start( aArc.GetP0() );
VECTOR2I end( aArc.GetP1() );
VECTOR2I center( aArc.GetCenter() );
EDA_ANGLE start_angle = aArc.GetStartAngle();
EDA_ANGLE end_angle = aArc.GetEndAngle();
if( !aPlotInRegion )
MoveTo( start);

View File

@ -154,13 +154,6 @@ double PLOTTER::GetDashGapLenIU() const
}
void PLOTTER::Arc( const SHAPE_ARC& aArc )
{
Arc( VECTOR2I( aArc.GetCenter() ), aArc.GetStartAngle(), aArc.GetEndAngle(), aArc.GetRadius(),
FILL_T::NO_FILL, aArc.GetWidth() );
}
void PLOTTER::Arc( const VECTOR2I& centre, double StAngle, double EndAngle, int radius,
FILL_T fill, int width )
{

View File

@ -222,7 +222,6 @@ public:
*/
virtual void Arc( const VECTOR2I& centre, double StAngle, double EndAngle, int rayon,
FILL_T fill, int width = USE_DEFAULT_LINE_WIDTH );
virtual void Arc( const SHAPE_ARC& aArc );
/**
* Generic fallback: Cubic Bezier curve rendered as a polyline

View File

@ -72,8 +72,6 @@ public:
virtual void Arc( const VECTOR2I& aCenter, double aStAngle, double aEndAngle, int aRadius,
FILL_T aFill, int aWidth = USE_DEFAULT_LINE_WIDTH ) override;
virtual void Arc( const SHAPE_ARC& aArc ) override;
// These functions plot an item and manage X2 gerber attributes
virtual void ThickSegment( const VECTOR2I& start, const VECTOR2I& end, int width,
OUTLINE_MODE tracemode, void* aData ) override;

View File

@ -190,19 +190,19 @@ public:
}
/**
* @return the central angle of the arc shape in degrees, normalized between 0.0, 360.0 deg.
* @return the central angle of the arc shape, normalized between 0..360 deg.
*/
double GetCentralAngle() const;
EDA_ANGLE GetCentralAngle() const;
/**
* @return the start angle of the arc shape in degrees, normalized between 0.0, 360.0 deg.
* @return the start angle of the arc shape, normalized between 0..360 deg.
*/
double GetStartAngle() const;
EDA_ANGLE GetStartAngle() const;
/**
* @return the end angle of the arc shape in degrees, normalized between 0.0, 360.0 deg.
* @return the end angle of the arc shape, normalized between 0..360 deg.
*/
double GetEndAngle() const;
EDA_ANGLE GetEndAngle() const;
/**
* @return the length of the arc shape.

View File

@ -561,15 +561,15 @@ void TransformArcToPolygon( SHAPE_POLY_SET& aCornerBuffer, const VECTOR2I& aStar
// Rotate these 2 corners to match the start and ens points of inner and outer
// end points of the arc appoximation outlines, build below.
// The final shape is much better.
double arc_angle_start_deg = arc.GetStartAngle();
double arc_angle = arc.GetCentralAngle();
double arc_angle_end_deg = arc_angle_start_deg + arc_angle;
EDA_ANGLE arc_angle_start = arc.GetStartAngle();
EDA_ANGLE arc_angle = arc.GetCentralAngle();
EDA_ANGLE arc_angle_end = arc_angle_start + arc_angle;
if( arc_angle_start_deg != 0 && arc_angle_start_deg != 180.0 )
polyshape.Outline(0).Rotate( arc_angle_start_deg * M_PI/180.0, aStart );
if( arc_angle_start != ANGLE_0 && arc_angle_start != ANGLE_180 )
polyshape.Outline(0).Rotate( arc_angle_start.AsRadians(), aStart );
if( arc_angle_end_deg != 0 && arc_angle_end_deg != 180.0 )
polyshape.Outline(1).Rotate( arc_angle_end_deg * M_PI/180.0, aEnd );
if( arc_angle_end != ANGLE_0 && arc_angle_end != ANGLE_180 )
polyshape.Outline(1).Rotate( arc_angle_end.AsRadians(), aEnd );
VECTOR2I center = arc.GetCenter();
int radius = arc.GetRadius();
@ -587,14 +587,12 @@ void TransformArcToPolygon( SHAPE_POLY_SET& aCornerBuffer, const VECTOR2I& aStar
polyshape.NewOutline();
ConvertArcToPolyline( polyshape.Outline(2), center, arc_outer_radius,
EDA_ANGLE( arc_angle_start_deg, DEGREES_T ),
EDA_ANGLE( arc_angle, DEGREES_T ), aError, errorLocOuter );
ConvertArcToPolyline( polyshape.Outline(2), center, arc_outer_radius, arc_angle_start,
arc_angle, aError, errorLocOuter );
if( arc_inner_radius > 0 )
ConvertArcToPolyline( polyshape.Outline(2), center, arc_inner_radius,
EDA_ANGLE( arc_angle_end_deg, DEGREES_T ),
-EDA_ANGLE( arc_angle, DEGREES_T ), aError, errorLocInner );
ConvertArcToPolyline( polyshape.Outline(2), center, arc_inner_radius, arc_angle_end,
-arc_angle, aError, errorLocInner );
else
polyshape.Append( center );
#else
@ -610,7 +608,7 @@ void TransformArcToPolygon( SHAPE_POLY_SET& aCornerBuffer, const VECTOR2I& aStar
std::vector<VECTOR2I> outside_pts;
// delta is the effective error approximation to build a polyline from an arc
int segCnt360 = arcSpine.GetSegmentCount()*360.0/arc.GetCentralAngle();;
int segCnt360 = arcSpine.GetSegmentCount()*360.0/arc.GetCentralAngle().AsDegrees();
int delta = CircleToEndSegmentDeltaRadius( radius+radial_offset, std::abs(segCnt360) );
/// We start by making rounded ends on the arc
@ -622,15 +620,15 @@ void TransformArcToPolygon( SHAPE_POLY_SET& aCornerBuffer, const VECTOR2I& aStar
// Rotate these 2 corners to match the start and ens points of inner and outer
// end points of the arc appoximation outlines, build below.
// The final shape is much better.
double arc_angle_end_deg = arc.GetStartAngle();
EDA_ANGLE arc_angle_end = arc.GetStartAngle();
if( arc_angle_end_deg != 0 && arc_angle_end_deg != 180.0 )
polyshape.Outline(0).Rotate( arc_angle_end_deg * M_PI/180.0, arcSpine.GetPoint( 0 ) );
if( arc_angle_end != ANGLE_0 && arc_angle_end != ANGLE_180 )
polyshape.Outline(0).Rotate( arc_angle_end.AsRadians(), arcSpine.GetPoint( 0 ) );
arc_angle_end_deg = arc.GetEndAngle();
if( arc_angle_end_deg != 0 && arc_angle_end_deg != 180.0 )
polyshape.Outline(1).Rotate( arc_angle_end_deg * M_PI/180.0, arcSpine.GetPoint( -1 ) );
if( arc_angle_end != ANGLE_0 && arc_angle_end != ANGLE_180 )
polyshape.Outline(1).Rotate( arc_angle_end.AsRadians(), arcSpine.GetPoint( -1 ) );
if( aErrorLoc == ERROR_OUTSIDE )
radial_offset += delta + defaultErr/2;

View File

@ -305,15 +305,15 @@ void SHAPE_ARC::update_bbox()
points.push_back( m_start );
points.push_back( m_end );
double start_angle = GetStartAngle();
double end_angle = start_angle + GetCentralAngle();
EDA_ANGLE start_angle = GetStartAngle();
EDA_ANGLE end_angle = start_angle + GetCentralAngle();
// we always count quadrants clockwise (increasing angle)
if( start_angle > end_angle )
std::swap( start_angle, end_angle );
int quad_angle_start = std::ceil( start_angle / 90.0 );
int quad_angle_end = std::floor( end_angle / 90.0 );
int quad_angle_start = std::ceil( start_angle.AsDegrees() / 90.0 );
int quad_angle_end = std::floor( end_angle.AsDegrees() / 90.0 );
// count through quadrants included in arc
for( int quad_angle = quad_angle_start; quad_angle <= quad_angle_end; ++quad_angle )
@ -323,14 +323,12 @@ void SHAPE_ARC::update_bbox()
switch( quad_angle % 4 )
{
case 0: quad_pt += { radius, 0 }; break;
case 1:
case -3: quad_pt += { 0, radius }; break;
case 2:
case -2: quad_pt += { -radius, 0 }; break;
case 3:
case -1: quad_pt += { 0, -radius }; break;
default: assert( false );
case 0: quad_pt += { radius, 0 }; break;
case 1: case -3: quad_pt += { 0, radius }; break;
case 2: case -2: quad_pt += { -radius, 0 }; break;
case 3: case -1: quad_pt += { 0, -radius }; break;
default:
assert( false );
}
points.push_back( quad_pt );
@ -353,7 +351,7 @@ const BOX2I SHAPE_ARC::BBox( int aClearance ) const
bool SHAPE_ARC::IsClockwise() const
{
return GetCentralAngle() < 0;
return GetCentralAngle() < ANGLE_0;
}
@ -375,10 +373,10 @@ bool SHAPE_ARC::Collide( const VECTOR2I& aP, int aClearance, int* aActual,
// If not a 360 degree arc, need to use arc angles to decide if point collides
if( m_start != m_end )
{
bool ccw = GetCentralAngle() > 0.0;
double rotatedVecAngle = NormalizeAngleDegreesPos( NormalizeAngleDegreesPos( RAD2DEG( vec.Angle() ) )
- GetStartAngle() );
double rotatedEndAngle = NormalizeAngleDegreesPos( GetEndAngle() - GetStartAngle() );
bool ccw = GetCentralAngle() > ANGLE_0;
EDA_ANGLE vecAngle( vec );
EDA_ANGLE rotatedVecAngle = ( vecAngle.Normalize() - GetStartAngle() ).Normalize();
EDA_ANGLE rotatedEndAngle = ( GetEndAngle() - GetStartAngle() ).Normalize();
if( ( ccw && rotatedVecAngle > rotatedEndAngle )
|| ( !ccw && rotatedVecAngle < rotatedEndAngle ) )
@ -404,23 +402,17 @@ bool SHAPE_ARC::Collide( const VECTOR2I& aP, int aClearance, int* aActual,
}
double SHAPE_ARC::GetStartAngle() const
EDA_ANGLE SHAPE_ARC::GetStartAngle() const
{
VECTOR2D d( m_start - GetCenter() );
auto ang = 180.0 / M_PI * atan2( d.y, d.x );
return NormalizeAngleDegrees( ang, 0.0, 360.0 );
EDA_ANGLE angle( m_start - GetCenter() );
return angle.Normalize();
}
double SHAPE_ARC::GetEndAngle() const
EDA_ANGLE SHAPE_ARC::GetEndAngle() const
{
VECTOR2D d( m_end - GetCenter() );
auto ang = 180.0 / M_PI * atan2( d.y, d.x );
return NormalizeAngleDegrees( ang, 0.0, 360.0 );
EDA_ANGLE angle( m_end - GetCenter() );
return angle.Normalize();
}
@ -433,19 +425,19 @@ VECTOR2I SHAPE_ARC::GetCenter() const
double SHAPE_ARC::GetLength() const
{
double radius = GetRadius();
double includedAngle = std::abs( GetCentralAngle() );
EDA_ANGLE includedAngle = GetCentralAngle();
return radius * M_PI * includedAngle / 180.0;
return std::abs( radius * includedAngle.AsRadians() );
}
double SHAPE_ARC::GetCentralAngle() const
EDA_ANGLE SHAPE_ARC::GetCentralAngle() const
{
VECTOR2I center = GetCenter();
EDA_ANGLE angle1 = EDA_ANGLE( m_mid - center ) - EDA_ANGLE( m_start - center );
EDA_ANGLE angle2 = EDA_ANGLE( m_end - center ) - EDA_ANGLE( m_mid - center );
return angle1.Normalize180().AsDegrees() + angle2.Normalize180().AsDegrees();
return angle1.Normalize180() + angle2.Normalize180();
}
@ -459,10 +451,10 @@ const SHAPE_LINE_CHAIN SHAPE_ARC::ConvertToPolyline( double aAccuracy,
double* aEffectiveAccuracy ) const
{
SHAPE_LINE_CHAIN rv;
double r = GetRadius();
double sa = GetStartAngle();
VECTOR2I c = GetCenter();
double ca = GetCentralAngle();
double r = GetRadius();
EDA_ANGLE sa = GetStartAngle();
VECTOR2I c = GetCenter();
EDA_ANGLE ca = GetCentralAngle();
int n;
@ -480,11 +472,10 @@ const SHAPE_LINE_CHAIN SHAPE_ARC::ConvertToPolyline( double aAccuracy,
}
else
{
double arc_angle = std::abs( ca );
n = GetArcToSegmentCount( external_radius, aAccuracy, EDA_ANGLE( arc_angle, DEGREES_T ) );
n = GetArcToSegmentCount( external_radius, aAccuracy, ca );
// Recalculate the effective error of approximation, that can be < aAccuracy
int seg360 = n * 360.0 / arc_angle;
int seg360 = n * 360.0 / ca.AsDegrees();
effectiveAccuracy = CircleToEndSegmentDeltaRadius( external_radius, seg360 );
}
@ -498,13 +489,13 @@ const SHAPE_LINE_CHAIN SHAPE_ARC::ConvertToPolyline( double aAccuracy,
for( int i = 1; i < n ; i += 2 )
{
double a = sa;
EDA_ANGLE a = sa;
if( n != 0 )
a += ( ca * i ) / n;
double x = c.x + r * cos( a * M_PI / 180.0 );
double y = c.y + r * sin( a * M_PI / 180.0 );
double x = c.x + r * cos( a.AsRadians() );
double y = c.y + r * sin( a.AsRadians() );
rv.Append( KiROUND( x ), KiROUND( y ) );
}
@ -589,13 +580,13 @@ SHAPE_ARC SHAPE_ARC::Reversed() const
bool SHAPE_ARC::sliceContainsPoint( const VECTOR2I& p ) const
{
VECTOR2I center = GetCenter();
double phi = 180.0 / M_PI * atan2( p.y - center.y, p.x - center.x );
double ca = GetCentralAngle();
double sa = GetStartAngle();
double ea;
VECTOR2I center = GetCenter();
EDA_ANGLE phi( p - center );
EDA_ANGLE ca = GetCentralAngle();
EDA_ANGLE sa = GetStartAngle();
EDA_ANGLE ea;
if( ca >= 0 )
if( ca >= ANGLE_0 )
{
ea = sa + ca;
}
@ -605,5 +596,5 @@ bool SHAPE_ARC::sliceContainsPoint( const VECTOR2I& p ) const
sa += ca;
}
return alg::within_wrapped_range( phi, sa, ea, 360.0 );
return alg::within_wrapped_range( phi.AsDegrees(), sa.AsDegrees(), ea.AsDegrees(), 360.0 );
}

View File

@ -186,8 +186,8 @@ void ROUTER_PREVIEW_ITEM::drawLineChain( const SHAPE_LINE_CHAIN_BASE* aL, KIGFX:
{
const SHAPE_ARC& arc = lineChain->CArcs()[s];
double start_angle = DEG2RAD( arc.GetStartAngle() );
double angle = DEG2RAD( arc.GetCentralAngle() );
double start_angle = arc.GetStartAngle().AsRadians();
double angle = arc.GetCentralAngle().AsRadians();
gal->DrawArc( arc.GetCenter(), arc.GetRadius(), start_angle, start_angle + angle);
}
@ -356,8 +356,8 @@ void ROUTER_PREVIEW_ITEM::drawShape( const SHAPE* aShape, KIGFX::GAL* gal ) cons
const SHAPE_ARC* arc = static_cast<const SHAPE_ARC*>( aShape );
const int w = arc->GetWidth();
auto start_angle = DEG2RAD( arc->GetStartAngle() );
auto angle = DEG2RAD( arc->GetCentralAngle() );
double start_angle = arc->GetStartAngle().AsRadians();
double angle = arc->GetCentralAngle().AsRadians();
gal->SetIsFill( false );
gal->SetIsStroke( true );

View File

@ -67,32 +67,39 @@ static void CheckArcGeom( const SHAPE_ARC& aArc, const ARC_PROPERTIES& aProps, c
BOOST_CHECK_PREDICATE( KI_TEST::IsVecWithinTol<VECTOR2I>,
( aProps.m_start_point )( aProps.m_start_point )( pos_tol ) );
BOOST_CHECK_PREDICATE(
KI_TEST::IsVecWithinTol<VECTOR2I>, ( aArc.GetP1() )( aProps.m_end_point )( pos_tol ) );
BOOST_CHECK_PREDICATE( KI_TEST::IsVecWithinTol<VECTOR2I>,
( aArc.GetP1() )( aProps.m_end_point )( pos_tol ) );
BOOST_CHECK_PREDICATE( KI_TEST::IsVecWithinTol<VECTOR2I>,
( aArc.GetCenter() )( aProps.m_center_point )( aSynErrIU ) );
BOOST_CHECK_PREDICATE( KI_TEST::IsWithinWrapped<double>,
( aArc.GetCentralAngle() )( aProps.m_center_angle )( 360.0 )( angle_tol_deg ) );
( aArc.GetCentralAngle().AsDegrees() )( aProps.m_center_angle )( 360.0 )( angle_tol_deg ) );
BOOST_CHECK_PREDICATE( KI_TEST::IsWithinWrapped<double>,
( aArc.GetStartAngle() )( aProps.m_start_angle )( 360.0 )( angle_tol_deg ) );
( aArc.GetStartAngle().AsDegrees() )( aProps.m_start_angle )( 360.0 )( angle_tol_deg ) );
BOOST_CHECK_PREDICATE( KI_TEST::IsWithinWrapped<double>,
( aArc.GetEndAngle() )( aProps.m_end_angle )( 360.0 )( angle_tol_deg ) );
BOOST_CHECK_PREDICATE(
KI_TEST::IsWithin<double>, ( aArc.GetRadius() )( aProps.m_radius )( aSynErrIU ) );
( aArc.GetEndAngle().AsDegrees() )( aProps.m_end_angle )( 360.0 )( angle_tol_deg ) );
BOOST_CHECK_PREDICATE( KI_TEST::IsWithin<double>,
( aArc.GetRadius() )( aProps.m_radius )( aSynErrIU ) );
/// Check the chord agrees
const auto chord = aArc.GetChord();
BOOST_CHECK_PREDICATE(
KI_TEST::IsVecWithinTol<VECTOR2I>, ( chord.A )( aProps.m_start_point )( pos_tol ) );
BOOST_CHECK_PREDICATE(
KI_TEST::IsVecWithinTol<VECTOR2I>, ( chord.B )( aProps.m_end_point )( pos_tol ) );
BOOST_CHECK_PREDICATE( KI_TEST::IsVecWithinTol<VECTOR2I>,
( chord.A )( aProps.m_start_point )( pos_tol ) );
BOOST_CHECK_PREDICATE( KI_TEST::IsVecWithinTol<VECTOR2I>,
( chord.B )( aProps.m_end_point )( pos_tol ) );
/// All arcs are solid
BOOST_CHECK_EQUAL( aArc.IsSolid(), true );
BOOST_CHECK_PREDICATE(
KI_TEST::IsBoxWithinTol<BOX2I>, ( aArc.BBox() )( aProps.m_bbox )( pos_tol ) );
BOOST_CHECK_PREDICATE( KI_TEST::IsBoxWithinTol<BOX2I>,
( aArc.BBox() )( aProps.m_bbox )( pos_tol ) );
/// Collisions will be checked elsewhere.
}

View File

@ -256,8 +256,8 @@ void PNS_LOG_VIEWER_OVERLAY::AnnotatedPoint( const VECTOR2I p, int size, std::st
void PNS_LOG_VIEWER_OVERLAY::Arc( const SHAPE_ARC& arc )
{
double radius = arc.GetRadius();
double start_angle = DEG2RAD( arc.GetStartAngle() );
double angle = DEG2RAD( arc.GetCentralAngle() );
double start_angle = arc.GetStartAngle().AsRadians();
double angle = arc.GetCentralAngle().AsRadians();
KIGFX::VIEW_OVERLAY::SetLineWidth( arc.GetWidth() / 10 );
KIGFX::VIEW_OVERLAY::Arc( arc.GetCenter(), radius, start_angle, start_angle + angle );

View File

@ -206,7 +206,7 @@ bool KICADCURVE::Read( SEXPR::SEXPR* aEntry, CURVE_TYPE aCurveType )
m_end.y = new_arc.GetP0().y/scale;
m_ep.x = new_arc.GetP1().x/scale;
m_ep.y = new_arc.GetP1().y/scale;
m_angle = new_arc.GetCentralAngle() / 180.0 * M_PI;
m_angle = new_arc.GetCentralAngle().AsRadians();
}
return true;