OPENGL_GAL::DrawArcSegment(): use a better number of segm to approximate the arc.
Previously, the count of segments used a magic number optimized for Pcbnew. This is not good, and does not work well on Gerbview. The count uses now a max error acceptable is approximation (5 microns in Gerbview and Pcbnew). Fixes #9101 https://gitlab.com/kicad/code/kicad/issues/9101
This commit is contained in:
parent
56ccaf6482
commit
36048fa436
|
@ -342,8 +342,10 @@ void CAIRO_GAL_BASE::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, doub
|
||||||
|
|
||||||
|
|
||||||
void CAIRO_GAL_BASE::DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadius,
|
void CAIRO_GAL_BASE::DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadius,
|
||||||
double aStartAngle, double aEndAngle, double aWidth )
|
double aStartAngle, double aEndAngle, double aWidth,
|
||||||
|
double aMaxError )
|
||||||
{
|
{
|
||||||
|
// Note: aMaxError is not used because Cairo can draw true arcs
|
||||||
if( m_isFillEnabled )
|
if( m_isFillEnabled )
|
||||||
{
|
{
|
||||||
m_lineWidth = aWidth;
|
m_lineWidth = aWidth;
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
#include <wx/frame.h>
|
#include <wx/frame.h>
|
||||||
|
|
||||||
#include <macros.h>
|
#include <macros.h>
|
||||||
|
#include <geometry/geometry_utils.h>
|
||||||
|
|
||||||
#ifdef KICAD_GAL_PROFILE
|
#ifdef KICAD_GAL_PROFILE
|
||||||
#include <profile.h>
|
#include <profile.h>
|
||||||
|
@ -850,8 +851,9 @@ void OPENGL_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double a
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void OPENGL_GAL::DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadius, double aStartAngle,
|
void OPENGL_GAL::DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadius,
|
||||||
double aEndAngle, double aWidth )
|
double aStartAngle, double aEndAngle,
|
||||||
|
double aWidth, double aMaxError )
|
||||||
{
|
{
|
||||||
if( aRadius <= 0 )
|
if( aRadius <= 0 )
|
||||||
{
|
{
|
||||||
|
@ -865,7 +867,10 @@ void OPENGL_GAL::DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadius, d
|
||||||
// Swap the angles, if start angle is greater than end angle
|
// Swap the angles, if start angle is greater than end angle
|
||||||
SWAP( aStartAngle, >, aEndAngle );
|
SWAP( aStartAngle, >, aEndAngle );
|
||||||
|
|
||||||
double alphaIncrement = calcAngleStep( aRadius );
|
// Calculate the seg count to approximate the arc with aMaxError or less
|
||||||
|
int segCount360 = GetArcToSegmentCount( aRadius, aMaxError, 360.0 );
|
||||||
|
segCount360 = std::max( CIRCLE_POINTS, segCount360 );
|
||||||
|
double alphaIncrement = 2.0 * M_PI / segCount360;
|
||||||
|
|
||||||
// Refinement: Use a segment count multiple of 2, because we have a control point
|
// Refinement: Use a segment count multiple of 2, because we have a control point
|
||||||
// on the middle of the arc, and the look is better if it is on a segment junction
|
// on the middle of the arc, and the look is better if it is on a segment junction
|
||||||
|
|
|
@ -351,7 +351,7 @@ void GERBVIEW_PAINTER::draw( /*const*/ GERBER_DRAW_ITEM* aItem, int aLayer )
|
||||||
endAngle = startAngle + 2*M_PI;
|
endAngle = startAngle + 2*M_PI;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_gal->DrawArcSegment( center, radius, startAngle, endAngle, width );
|
m_gal->DrawArcSegment( center, radius, startAngle, endAngle, width, ARC_HIGH_DEF );
|
||||||
|
|
||||||
#if 0 // Arc Debugging only
|
#if 0 // Arc Debugging only
|
||||||
m_gal->SetIsFill( false );
|
m_gal->SetIsFill( false );
|
||||||
|
|
|
@ -82,8 +82,10 @@ public:
|
||||||
double aStartAngle, double aEndAngle ) override;
|
double aStartAngle, double aEndAngle ) override;
|
||||||
|
|
||||||
/// @copydoc GAL::DrawArcSegment()
|
/// @copydoc GAL::DrawArcSegment()
|
||||||
|
/// Note: aMaxError is not used in Cairo, because Cairo can draw true arcs
|
||||||
void DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadius,
|
void DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadius,
|
||||||
double aStartAngle, double aEndAngle, double aWidth ) override;
|
double aStartAngle, double aEndAngle, double aWidth,
|
||||||
|
double aMaxError ) override;
|
||||||
|
|
||||||
/// @copydoc GAL::DrawRectangle()
|
/// @copydoc GAL::DrawRectangle()
|
||||||
void DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint ) override;
|
void DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint ) override;
|
||||||
|
|
|
@ -151,9 +151,11 @@ public:
|
||||||
* @param aStartAngle is the start angle of the arc.
|
* @param aStartAngle is the start angle of the arc.
|
||||||
* @param aEndAngle is the end angle of the arc.
|
* @param aEndAngle is the end angle of the arc.
|
||||||
* @param aWidth is the thickness of the arc (pen size).
|
* @param aWidth is the thickness of the arc (pen size).
|
||||||
|
* @param aMaxError is the max allowed error to create segments to approximate a circle.
|
||||||
|
* It has meaning only for back ends that can't draw a true arc, and use segments to approximate.
|
||||||
*/
|
*/
|
||||||
virtual void DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadius, double aStartAngle,
|
virtual void DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadius, double aStartAngle,
|
||||||
double aEndAngle, double aWidth ) {};
|
double aEndAngle, double aWidth, double aMaxError ) {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draw a rectangle.
|
* Draw a rectangle.
|
||||||
|
|
|
@ -128,7 +128,8 @@ public:
|
||||||
|
|
||||||
/// @copydoc GAL::DrawArcSegment()
|
/// @copydoc GAL::DrawArcSegment()
|
||||||
void DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadius,
|
void DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadius,
|
||||||
double aStartAngle, double aEndAngle, double aWidth ) override;
|
double aStartAngle, double aEndAngle, double aWidth,
|
||||||
|
double aMaxError ) override;
|
||||||
|
|
||||||
/// @copydoc GAL::DrawRectangle()
|
/// @copydoc GAL::DrawRectangle()
|
||||||
void DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint ) override;
|
void DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint ) override;
|
||||||
|
|
|
@ -683,7 +683,7 @@ void PCB_PAINTER::draw( const PCB_ARC* aArc, int aLayer )
|
||||||
m_gal->SetIsFill( not outline_mode );
|
m_gal->SetIsFill( not outline_mode );
|
||||||
m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth );
|
m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth );
|
||||||
|
|
||||||
m_gal->DrawArcSegment( center, radius, start_angle, start_angle + angle, width );
|
m_gal->DrawArcSegment( center, radius, start_angle, start_angle + angle, width, ARC_HIGH_DEF );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clearance lines
|
// Clearance lines
|
||||||
|
@ -700,7 +700,7 @@ void PCB_PAINTER::draw( const PCB_ARC* aArc, int aLayer )
|
||||||
m_gal->SetStrokeColor( color );
|
m_gal->SetStrokeColor( color );
|
||||||
|
|
||||||
m_gal->DrawArcSegment( center, radius, start_angle, start_angle + angle,
|
m_gal->DrawArcSegment( center, radius, start_angle, start_angle + angle,
|
||||||
width + clearance * 2 );
|
width + clearance * 2, ARC_HIGH_DEF );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Debug only: enable this code only to test the TransformArcToPolygon function
|
// Debug only: enable this code only to test the TransformArcToPolygon function
|
||||||
|
@ -1081,7 +1081,7 @@ void PCB_PAINTER::draw( const PAD* aPad, int aLayer )
|
||||||
std::unique_ptr<PAD> dummyPad;
|
std::unique_ptr<PAD> dummyPad;
|
||||||
std::shared_ptr<SHAPE_COMPOUND> shapes;
|
std::shared_ptr<SHAPE_COMPOUND> shapes;
|
||||||
|
|
||||||
// Drawing components of compound shapes in outline mode produces a mess.
|
// Drawing components of compound shapes in outline mode produces a mess.
|
||||||
bool simpleShapes = !m_pcbSettings.m_sketchMode[LAYER_PADS_TH];
|
bool simpleShapes = !m_pcbSettings.m_sketchMode[LAYER_PADS_TH];
|
||||||
|
|
||||||
if( simpleShapes )
|
if( simpleShapes )
|
||||||
|
@ -1416,7 +1416,7 @@ void PCB_PAINTER::draw( const PCB_SHAPE* aShape, int aLayer )
|
||||||
m_gal->DrawArcSegment( start, aShape->GetRadius(),
|
m_gal->DrawArcSegment( start, aShape->GetRadius(),
|
||||||
DECIDEG2RAD( aShape->GetArcAngleStart() ),
|
DECIDEG2RAD( aShape->GetArcAngleStart() ),
|
||||||
DECIDEG2RAD( aShape->GetArcAngleStart() + aShape->GetAngle() ), // Change this
|
DECIDEG2RAD( aShape->GetArcAngleStart() + aShape->GetAngle() ), // Change this
|
||||||
thickness );
|
thickness, ARC_HIGH_DEF );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1426,7 +1426,7 @@ void PCB_PAINTER::draw( const PCB_SHAPE* aShape, int aLayer )
|
||||||
m_gal->DrawArcSegment( start, aShape->GetRadius(),
|
m_gal->DrawArcSegment( start, aShape->GetRadius(),
|
||||||
DECIDEG2RAD( aShape->GetArcAngleStart() ),
|
DECIDEG2RAD( aShape->GetArcAngleStart() ),
|
||||||
DECIDEG2RAD( aShape->GetArcAngleStart() + aShape->GetAngle() ), // Change this
|
DECIDEG2RAD( aShape->GetArcAngleStart() + aShape->GetAngle() ), // Change this
|
||||||
thickness );
|
thickness, ARC_HIGH_DEF );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue