From fa49b54f93b0d6bae6f5cf2e61cb274e6d558cb7 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Mon, 28 Jun 2021 15:50:16 +0200 Subject: [PATCH] Fix minor issue in TransformCircleToPolygon() when aError is set to a large value. pcb_painter.cpp: add (but not activate) compil option to show the conversion of SHAPE_ARC::ConvertToPolyline as segments, for debug purposes. --- .../src/convert_basic_shapes_to_polygon.cpp | 5 ++++- libs/kimath/src/geometry/geometry_utils.cpp | 10 +++++---- pcbnew/pcb_painter.cpp | 21 ++++++++++++++++++- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/libs/kimath/src/convert_basic_shapes_to_polygon.cpp b/libs/kimath/src/convert_basic_shapes_to_polygon.cpp index a5e1710d53..e770c5c62c 100644 --- a/libs/kimath/src/convert_basic_shapes_to_polygon.cpp +++ b/libs/kimath/src/convert_basic_shapes_to_polygon.cpp @@ -55,7 +55,10 @@ void TransformCircleToPolygon( SHAPE_LINE_CHAIN& aCornerBuffer, wxPoint aCenter, int radius = aRadius; if( aErrorLoc == ERROR_OUTSIDE ) - radius += GetCircleToPolyCorrection( aError ); + { + int actual_error = GetCircleToSegmentError( radius, numSegs ); + radius += GetCircleToPolyCorrection( actual_error ); + } for( int angle = 0; angle < 3600; angle += delta ) { diff --git a/libs/kimath/src/geometry/geometry_utils.cpp b/libs/kimath/src/geometry/geometry_utils.cpp index a9d426b373..a712031b6e 100644 --- a/libs/kimath/src/geometry/geometry_utils.cpp +++ b/libs/kimath/src/geometry/geometry_utils.cpp @@ -66,12 +66,14 @@ int GetArcToSegmentCount( int aRadius, int aErrorMax, double aArcAngleDegree ) int GetCircleToSegmentError( int aRadius, int aSegCount ) { - // avoid divide-by-zero, and the minimal seg count used here = 2 - // (giving error = aRadius) - aSegCount = std::max( 2, aSegCount ); + // This is similar to the "inverse" of GetArcToSegmentCount() + + // The minimal seg count is 2, giving error = aRadius + if( aSegCount <= 2 ) + return aRadius; double alpha = M_PI / aSegCount; - double error = aRadius * ( 1.0 - cos( alpha) ); + int error = KiROUND( aRadius * ( 1.0 - cos( alpha) ) ); return error; } diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index 98b96ccbef..286c025dfa 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -713,9 +713,28 @@ void PCB_PAINTER::draw( const PCB_ARC* aArc, int aLayer ) m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth ); m_gal->SetIsFill( false ); m_gal->SetIsStroke( true ); - m_gal->SetStrokeColor( color ); + m_gal->SetStrokeColor( COLOR4D( 0, 0, 1.0, 1.0 ) ); m_gal->DrawPolygon( cornerBuffer ); #endif + +// Debug only: enable this code only to test the SHAPE_ARC::ConvertToPolyline function +// and display the polyline created by it. +#if 0 + int error_value2 = aArc->GetBoard()->GetDesignSettings().m_MaxError; + SHAPE_ARC arc( aArc->GetCenter(), aArc->GetStart(), + aArc->GetAngle() / 10.0, aArc->GetWidth() ); + SHAPE_LINE_CHAIN arcSpine = arc.ConvertToPolyline( error_value2 ); + m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth ); + m_gal->SetIsFill( false ); + m_gal->SetIsStroke( true ); + m_gal->SetStrokeColor( COLOR4D( 0.3, 0.2, 0.5, 1.0 ) ); + + for( int idx = 1; idx < arcSpine.PointCount(); idx++ ) + { + m_gal->DrawSegment( arcSpine.CPoint( idx-1 ), arcSpine.CPoint( idx ), + aArc->GetWidth() ); + }; +#endif }