Merge branch 'meanders-1' into 'master'

Length tuning: allow larger radius in meanders.

See merge request kicad/code/kicad!1826
This commit is contained in:
dsa-t 2025-09-10 14:29:26 +03:00
commit 83f28a4858
2 changed files with 72 additions and 38 deletions

View File

@ -365,11 +365,12 @@ int MEANDER_SHAPE::MinAmplitude() const
}
int MEANDER_SHAPE::cornerRadius() const
int MEANDER_SHAPE::cornerRadius( bool aMid ) const
{
if( m_amplitude == 0 )
return 0;
// Compute min corner radius
int minCr = 0;
if( m_placer->MeanderSettings().m_cornerStyle == MEANDER_STYLE_ROUND )
@ -377,8 +378,18 @@ int MEANDER_SHAPE::cornerRadius() const
else
minCr = std::abs( m_baselineOffset ) + m_width / 2 * ( 1 - tan( DEG2RAD( 22.5 ) ) );
int maxCr1 = ( m_amplitude + std::abs( m_baselineOffset ) ) / 2;
// Compute max control radius 1
int maxCr1 = 0;
if( aMid )
maxCr1 = m_amplitude + std::abs( m_baselineOffset );
else
maxCr1 = ( m_amplitude + std::abs( m_baselineOffset ) ) / 2;
// Compute max control radius 2
int maxCr2 = spacing() / 2;
// Compute final max corner radius
int maxCr = std::min( maxCr1, maxCr2 );
wxCHECK2_MSG( maxCr >= minCr, return maxCr,
@ -525,7 +536,9 @@ SHAPE_LINE_CHAIN MEANDER_SHAPE::genMeanderShape( const VECTOR2D& aP, const VECTO
bool aSide, MEANDER_TYPE aType,
int aBaselineOffset )
{
int cr = cornerRadius();
int crEnds = cornerRadius( false );
int crMid = cornerRadius( true );
int offset = aBaselineOffset;
int spc = spacing();
int amplitude = m_amplitude;
@ -537,22 +550,27 @@ SHAPE_LINE_CHAIN MEANDER_SHAPE::genMeanderShape( const VECTOR2D& aP, const VECTO
VECTOR2D dir_u_b( aDir.Resize( offset ) );
VECTOR2D dir_v_b( dir_u_b.Perpendicular() );
if( 2 * cr > amplitude + std::abs( offset ) )
cr = ( amplitude + std::abs( offset ) ) / 2;
// Limit maximum corner radius
crEnds = std::min( crEnds, ( amplitude + std::abs( offset ) ) / 2 );
crMid = std::min( crMid, amplitude + std::abs( offset ) );
if( 2 * cr > spc )
cr = spc / 2;
// Corner radiuses must be between DP offset and half the spacing
crEnds = std::clamp( crEnds, offset, spc / 2 );
crMid = std::clamp( crMid, offset, spc / 2 );
if( cr - offset < 0 )
cr = offset;
m_meanCornerRadius = ( crEnds + crMid ) / 2;
m_meanCornerRadius = cr;
int crEndsMinus = crEnds - offset;
int crEndsPlus = crEnds + offset;
int sCorner = cr - offset;
int uCorner = cr + offset;
int startSide = amplitude - 2 * cr + std::abs( offset );
int turnSide = amplitude - cr;
int top = spc - 2 * cr;
int crMidMinus = crMid - offset;
int crMidPlus = crMid + offset;
int startSide = amplitude - 2 * crEnds + std::abs( offset );
int turnSide = amplitude - crMid + std::abs( offset );
int topEnds = spc - 2 * crEnds;
int topMid = spc - 2 * crMid;
SHAPE_LINE_CHAIN lc;
@ -567,32 +585,50 @@ SHAPE_LINE_CHAIN MEANDER_SHAPE::genMeanderShape( const VECTOR2D& aP, const VECTO
}
case MT_START:
{
if( targetBaseLen )
top = std::max( top, targetBaseLen - sCorner - uCorner * 2 + offset );
int topVal = ( topEnds + topMid ) / 2;
if( targetBaseLen )
{
topVal = std::max( topVal,
targetBaseLen - crEndsMinus - crEndsPlus - crMidPlus + offset );
}
miter( crEndsMinus, false );
forward( startSide );
miter( crEndsPlus, true );
forward( topVal );
miter( crMidPlus, true );
forward( turnSide );
miter( sCorner, false );
uShape( startSide, uCorner, top );
forward( std::min( sCorner, uCorner ) );
forward( std::abs( offset ) );
break;
}
case MT_FINISH:
{
int topVal = ( topEnds + topMid ) / 2;
if( targetBaseLen )
top = std::max( top, targetBaseLen - cr - spc );
{
int topVal = std::max( topVal,
targetBaseLen - crMidPlus - crEndsPlus - crEndsMinus + offset );
}
start( &lc, aP - dir_u_b, aDir );
turn( -ANGLE_90 );
forward( std::min( sCorner, uCorner ) );
forward( std::abs( offset ) );
uShape( startSide, uCorner, top );
miter( sCorner, false );
if( targetBaseLen >= spc + cr )
forward( turnSide );
miter( crMidPlus, true );
forward( topVal );
miter( crEndsPlus, true );
forward( startSide );
miter( crEndsMinus, false );
if( targetBaseLen >= spc + crEnds )
lc.Append( aP + dir_v_b + aDir.Resize( targetBaseLen ) );
else
lc.Append( aP + dir_v_b + aDir.Resize( 2 * spc - cr ) );
lc.Append( aP + dir_v_b + aDir.Resize( 2 * spc - crEnds ) );
break;
}
@ -600,24 +636,22 @@ SHAPE_LINE_CHAIN MEANDER_SHAPE::genMeanderShape( const VECTOR2D& aP, const VECTO
case MT_TURN:
{
if( targetBaseLen )
top = std::max( top, targetBaseLen - uCorner * 2 + offset * 2 );
topMid = std::max( topMid, targetBaseLen - crEndsPlus * 2 + offset * 2 );
start( &lc, aP - dir_u_b, aDir );
turn( -ANGLE_90 );
forward( std::abs( offset ) );
uShape( turnSide, uCorner, top );
forward( std::abs( offset ) );
uShape( turnSide, crMidPlus, topMid );
break;
}
case MT_SINGLE:
{
if( targetBaseLen )
top = std::max( top, ( targetBaseLen - sCorner * 2 - uCorner * 2 ) / 2 );
topEnds = std::max( topEnds, ( targetBaseLen - crEndsMinus * 2 - crEndsPlus * 2 ) / 2 );
miter( sCorner, false );
uShape( startSide, uCorner, top );
miter( sCorner, false );
miter( crEndsMinus, false );
uShape( startSide, crEndsPlus, topEnds );
miter( crEndsMinus, false );
lc.Append( aP + dir_v_b + aDir.Resize( 2 * spc ) );
break;
}

View File

@ -381,8 +381,8 @@ private:
///< Recalculate the clipped baseline after the parameters of the meander have been changed.
void updateBaseSegment();
///< Return sanitized corner radius value.
int cornerRadius() const;
///< Return sanitized corner radius value. Set \a aMid when meandering continues (U-turns).
int cornerRadius( bool aMid = true ) const;
///< Return sanitized spacing value.
int spacing() const;