Refinements in Arc to Polygon transform: slightly better shapes of arc ends.
Note also the transform is still not good: the same parameters are applied to convert inner arc, outer arc and middle arc of a thick arc to segments. But these parameters depend on arc radius (or circle radius) value.
This commit is contained in:
parent
e50eaed7b9
commit
3c81403424
|
@ -2,7 +2,7 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2018 CERN
|
* Copyright (C) 2018 CERN
|
||||||
* Copyright (C) 2019-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 2019-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -61,7 +61,7 @@ public:
|
||||||
*/
|
*/
|
||||||
SHAPE_ARC( const VECTOR2I& aArcStart, const VECTOR2I& aArcMid, const VECTOR2I& aArcEnd,
|
SHAPE_ARC( const VECTOR2I& aArcStart, const VECTOR2I& aArcMid, const VECTOR2I& aArcEnd,
|
||||||
int aWidth );
|
int aWidth );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SHAPE_ARC ctor.
|
* SHAPE_ARC ctor.
|
||||||
* Builds a SHAPE_ARC which is tangent to two segments and a given radius
|
* Builds a SHAPE_ARC which is tangent to two segments and a given radius
|
||||||
|
@ -144,8 +144,19 @@ public:
|
||||||
return SEG( m_start, m_end );
|
return SEG( m_start, m_end );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the central angle of the arc shape in degrees, normalized between 0.0, 360.0 deg
|
||||||
|
*/
|
||||||
double GetCentralAngle() const;
|
double GetCentralAngle() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the start angle of the arc shape in degrees, normalized between 0.0, 360.0 deg
|
||||||
|
*/
|
||||||
double GetStartAngle() const;
|
double GetStartAngle() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the end angle of the arc shape in degrees, normalized between 0.0, 360.0 deg
|
||||||
|
*/
|
||||||
double GetEndAngle() const;
|
double GetEndAngle() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -43,6 +43,14 @@ void TransformCircleToPolygon( SHAPE_LINE_CHAIN& aCornerBuffer, wxPoint aCenter,
|
||||||
{
|
{
|
||||||
wxPoint corner_position;
|
wxPoint corner_position;
|
||||||
int numSegs = GetArcToSegmentCount( aRadius, aError, 360.0 );
|
int numSegs = GetArcToSegmentCount( aRadius, aError, 360.0 );
|
||||||
|
|
||||||
|
// The shape will be built with a even number of segs. Reason: the horizontal
|
||||||
|
// diameter begins and ends to points on the actual circle, or circle
|
||||||
|
// expanded by aError if aErrorLoc == ERROR_OUTSIDE.
|
||||||
|
// This is used by Arc to Polygon shape convert.
|
||||||
|
if( numSegs & 1 )
|
||||||
|
numSegs++;
|
||||||
|
|
||||||
int delta = 3600 / numSegs; // rotate angle in 0.1 degree
|
int delta = 3600 / numSegs; // rotate angle in 0.1 degree
|
||||||
int radius = aRadius;
|
int radius = aRadius;
|
||||||
|
|
||||||
|
@ -67,6 +75,14 @@ void TransformCircleToPolygon( SHAPE_POLY_SET& aCornerBuffer, wxPoint aCenter, i
|
||||||
{
|
{
|
||||||
wxPoint corner_position;
|
wxPoint corner_position;
|
||||||
int numSegs = GetArcToSegmentCount( aRadius, aError, 360.0 );
|
int numSegs = GetArcToSegmentCount( aRadius, aError, 360.0 );
|
||||||
|
|
||||||
|
// The shape will be built with a even number of segs. Reason: the horizontal
|
||||||
|
// diameter begins and ends to points on the actual circle, or circle
|
||||||
|
// expanded by aError if aErrorLoc == ERROR_OUTSIDE.
|
||||||
|
// This is used by Arc to Polygon shape convert.
|
||||||
|
if( numSegs & 1 )
|
||||||
|
numSegs++;
|
||||||
|
|
||||||
int delta = 3600 / numSegs; // rotate angle in 0.1 degree
|
int delta = 3600 / numSegs; // rotate angle in 0.1 degree
|
||||||
int radius = aRadius;
|
int radius = aRadius;
|
||||||
|
|
||||||
|
@ -367,6 +383,21 @@ void TransformArcToPolygon( SHAPE_POLY_SET& aCornerBuffer, wxPoint aStart, wxPoi
|
||||||
wxPoint( arcSpine.GetPoint( -1 ).x, arcSpine.GetPoint( -1 ).y ), radial_offset, aError,
|
wxPoint( arcSpine.GetPoint( -1 ).x, arcSpine.GetPoint( -1 ).y ), radial_offset, aError,
|
||||||
aErrorLoc );
|
aErrorLoc );
|
||||||
|
|
||||||
|
// The circle polygon is built with a even number of segments, so the
|
||||||
|
// horizontal diameter has 2 corners on the biggest diameter
|
||||||
|
// 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();
|
||||||
|
|
||||||
|
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 ) );
|
||||||
|
|
||||||
|
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( aErrorLoc == ERROR_OUTSIDE )
|
if( aErrorLoc == ERROR_OUTSIDE )
|
||||||
radial_offset += aError;
|
radial_offset += aError;
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue