P&S: support for 45-degree style length tuning meanders
This commit is contained in:
parent
a2ac1cd087
commit
bcf7990bf9
|
@ -34,7 +34,7 @@ DIALOG_PNS_LENGTH_TUNING_SETTINGS::DIALOG_PNS_LENGTH_TUNING_SETTINGS( wxWindow*
|
||||||
m_settings( aSettings ),
|
m_settings( aSettings ),
|
||||||
m_mode( aMode )
|
m_mode( aMode )
|
||||||
{
|
{
|
||||||
m_miterStyle->Enable( false );
|
m_miterStyle->Enable( true );
|
||||||
m_radiusText->Enable( aMode != PNS_MODE_TUNE_DIFF_PAIR );
|
m_radiusText->Enable( aMode != PNS_MODE_TUNE_DIFF_PAIR );
|
||||||
//m_minAmpl.Enable ( aMode != PNS_MODE_TUNE_DIFF_PAIR_SKEW );
|
//m_minAmpl.Enable ( aMode != PNS_MODE_TUNE_DIFF_PAIR_SKEW );
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ DIALOG_PNS_LENGTH_TUNING_SETTINGS::DIALOG_PNS_LENGTH_TUNING_SETTINGS( wxWindow*
|
||||||
m_spacing.SetValue( m_settings.m_spacing );
|
m_spacing.SetValue( m_settings.m_spacing );
|
||||||
m_radiusText->SetValue( wxString::Format( wxT( "%i" ), m_settings.m_cornerRadiusPercentage ) );
|
m_radiusText->SetValue( wxString::Format( wxT( "%i" ), m_settings.m_cornerRadiusPercentage ) );
|
||||||
|
|
||||||
m_miterStyle->SetSelection( m_settings.m_cornerType == PNS_MEANDER_SETTINGS::ROUND ? 1 : 0 );
|
m_miterStyle->SetSelection( m_settings.m_cornerStyle == MEANDER_STYLE_ROUND ? 1 : 0 );
|
||||||
|
|
||||||
switch( aMode )
|
switch( aMode )
|
||||||
{
|
{
|
||||||
|
@ -97,7 +97,7 @@ void DIALOG_PNS_LENGTH_TUNING_SETTINGS::OnOkClick( wxCommandEvent& aEvent )
|
||||||
if( m_settings.m_maxAmplitude < m_settings.m_minAmplitude )
|
if( m_settings.m_maxAmplitude < m_settings.m_minAmplitude )
|
||||||
m_settings.m_maxAmplitude = m_settings.m_minAmplitude;
|
m_settings.m_maxAmplitude = m_settings.m_minAmplitude;
|
||||||
|
|
||||||
m_settings.m_cornerType = m_miterStyle->GetSelection() ? PNS_MEANDER_SETTINGS::CHAMFER : PNS_MEANDER_SETTINGS::ROUND;
|
m_settings.m_cornerStyle = m_miterStyle->GetSelection() ? MEANDER_STYLE_ROUND : MEANDER_STYLE_CHAMFER;
|
||||||
|
|
||||||
EndModal( wxID_OK );
|
EndModal( wxID_OK );
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "pns_meander.h"
|
#include "pns_meander.h"
|
||||||
#include "pns_meander_placer_base.h"
|
#include "pns_meander_placer_base.h"
|
||||||
#include "pns_router.h"
|
#include "pns_router.h"
|
||||||
|
#include "pns_debug_decorator.h"
|
||||||
|
|
||||||
const PNS_MEANDER_SETTINGS& PNS_MEANDER_SHAPE::Settings() const
|
const PNS_MEANDER_SETTINGS& PNS_MEANDER_SHAPE::Settings() const
|
||||||
{
|
{
|
||||||
|
@ -163,9 +164,7 @@ void PNS_MEANDERED_LINE::MeanderSegment( const SEG& aBase, int aBaseIndex )
|
||||||
|
|
||||||
int PNS_MEANDER_SHAPE::cornerRadius() const
|
int PNS_MEANDER_SHAPE::cornerRadius() const
|
||||||
{
|
{
|
||||||
int cr = (int64_t) spacing() * Settings().m_cornerRadiusPercentage / 200;
|
return (int64_t) spacing() * Settings().m_cornerRadiusPercentage / 200;
|
||||||
|
|
||||||
return cr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -181,7 +180,7 @@ int PNS_MEANDER_SHAPE::spacing( ) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SHAPE_LINE_CHAIN PNS_MEANDER_SHAPE::circleQuad( VECTOR2D aP, VECTOR2D aDir, bool aSide )
|
SHAPE_LINE_CHAIN PNS_MEANDER_SHAPE::makeMiterShape( VECTOR2D aP, VECTOR2D aDir, bool aSide )
|
||||||
{
|
{
|
||||||
SHAPE_LINE_CHAIN lc;
|
SHAPE_LINE_CHAIN lc;
|
||||||
|
|
||||||
|
@ -193,32 +192,57 @@ SHAPE_LINE_CHAIN PNS_MEANDER_SHAPE::circleQuad( VECTOR2D aP, VECTOR2D aDir, bool
|
||||||
|
|
||||||
VECTOR2D dir_u( aDir );
|
VECTOR2D dir_u( aDir );
|
||||||
VECTOR2D dir_v( aDir.Perpendicular( ) );
|
VECTOR2D dir_v( aDir.Perpendicular( ) );
|
||||||
|
|
||||||
const int ArcSegments = Settings().m_cornerArcSegments;
|
|
||||||
|
|
||||||
double radius = (double) aDir.EuclideanNorm();
|
|
||||||
double angleStep = M_PI / 2.0 / (double) ArcSegments;
|
|
||||||
|
|
||||||
double correction = 12.0 * radius * ( 1.0 - cos( angleStep / 2.0 ) );
|
|
||||||
|
|
||||||
if( !m_dual )
|
|
||||||
correction = 0.0;
|
|
||||||
else if( radius < m_meanCornerRadius )
|
|
||||||
correction = 0.0;
|
|
||||||
|
|
||||||
VECTOR2D p = aP;
|
VECTOR2D p = aP;
|
||||||
lc.Append( ( int ) p.x, ( int ) p.y );
|
lc.Append( ( int ) p.x, ( int ) p.y );
|
||||||
|
|
||||||
VECTOR2D dir_uu = dir_u.Resize( radius - correction );
|
|
||||||
VECTOR2D dir_vv = dir_v.Resize( radius - correction );
|
|
||||||
|
|
||||||
VECTOR2D shift = dir_u.Resize( correction );
|
PNS_DEBUG_DECORATOR *dbg = PNS_ROUTER::GetInstance()->GetInterface()->GetDebugDecorator();
|
||||||
|
// fixme: refactor
|
||||||
for( int i = ArcSegments - 1; i >= 0; i-- )
|
switch (m_placer->MeanderSettings().m_cornerStyle)
|
||||||
{
|
{
|
||||||
double alpha = (double) i / (double) ( ArcSegments - 1 ) * M_PI / 2.0;
|
case MEANDER_STYLE_ROUND:
|
||||||
p = aP + shift + dir_uu * cos( alpha ) + dir_vv * ( aSide ? -1.0 : 1.0 ) * ( 1.0 - sin( alpha ) );
|
{
|
||||||
|
const int ArcSegments = Settings().m_cornerArcSegments;
|
||||||
|
|
||||||
|
double radius = (double) aDir.EuclideanNorm();
|
||||||
|
double angleStep = M_PI / 2.0 / (double) ArcSegments;
|
||||||
|
|
||||||
|
double correction = 12.0 * radius * ( 1.0 - cos( angleStep / 2.0 ) );
|
||||||
|
|
||||||
|
if( !m_dual )
|
||||||
|
correction = 0.0;
|
||||||
|
else if( radius < m_meanCornerRadius )
|
||||||
|
correction = 0.0;
|
||||||
|
|
||||||
|
VECTOR2D dir_uu = dir_u.Resize( radius - correction );
|
||||||
|
VECTOR2D dir_vv = dir_v.Resize( radius - correction );
|
||||||
|
|
||||||
|
VECTOR2D shift = dir_u.Resize( correction );
|
||||||
|
|
||||||
|
for( int i = ArcSegments - 1; i >= 0; i-- )
|
||||||
|
{
|
||||||
|
double alpha = (double) i / (double) ( ArcSegments - 1 ) * M_PI / 2.0;
|
||||||
|
p = aP + shift + dir_uu * cos( alpha ) + dir_vv * ( aSide ? -1.0 : 1.0 ) * ( 1.0 - sin( alpha ) );
|
||||||
|
lc.Append( ( int ) p.x, ( int ) p.y );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MEANDER_STYLE_CHAMFER:
|
||||||
|
{
|
||||||
|
double radius = (double) aDir.EuclideanNorm();
|
||||||
|
double correction = 0;
|
||||||
|
if( m_dual && radius > m_meanCornerRadius )
|
||||||
|
correction = (double)(m_baselineOffset * 2) * tan ( 22.5 * M_PI / 180.0 );
|
||||||
|
|
||||||
|
VECTOR2D dir_cu = dir_u.Resize( correction );
|
||||||
|
VECTOR2D dir_cv = dir_v.Resize( correction );
|
||||||
|
|
||||||
|
p = aP - dir_cu;
|
||||||
lc.Append( ( int ) p.x, ( int ) p.y );
|
lc.Append( ( int ) p.x, ( int ) p.y );
|
||||||
|
p = aP + dir_u + (dir_v + dir_cv) * ( aSide ? -1.0 : 1.0 );
|
||||||
|
lc.Append( ( int ) p.x, ( int ) p.y );
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p = aP + dir_u + dir_v * ( aSide ? -1.0 : 1.0 );
|
p = aP + dir_u + dir_v * ( aSide ? -1.0 : 1.0 );
|
||||||
|
@ -270,7 +294,7 @@ void PNS_MEANDER_SHAPE::turn( int aAngle )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PNS_MEANDER_SHAPE::arc( int aRadius, bool aSide )
|
void PNS_MEANDER_SHAPE::miter( int aRadius, bool aSide )
|
||||||
{
|
{
|
||||||
if( aRadius <= 0 )
|
if( aRadius <= 0 )
|
||||||
{
|
{
|
||||||
|
@ -279,20 +303,21 @@ void PNS_MEANDER_SHAPE::arc( int aRadius, bool aSide )
|
||||||
}
|
}
|
||||||
|
|
||||||
VECTOR2D dir = m_currentDir.Resize( (double) aRadius );
|
VECTOR2D dir = m_currentDir.Resize( (double) aRadius );
|
||||||
SHAPE_LINE_CHAIN arc = circleQuad( m_currentPos, dir, aSide );
|
SHAPE_LINE_CHAIN lc = makeMiterShape( m_currentPos, dir, aSide );
|
||||||
m_currentPos = arc.CPoint( -1 );
|
|
||||||
|
m_currentPos = lc.CPoint( -1 );
|
||||||
m_currentDir = dir.Rotate( aSide ? -M_PI / 2.0 : M_PI / 2.0 );
|
m_currentDir = dir.Rotate( aSide ? -M_PI / 2.0 : M_PI / 2.0 );
|
||||||
|
|
||||||
m_currentTarget->Append ( arc );
|
m_currentTarget->Append ( lc );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PNS_MEANDER_SHAPE::uShape( int aSides, int aCorner, int aTop )
|
void PNS_MEANDER_SHAPE::uShape( int aSides, int aCorner, int aTop )
|
||||||
{
|
{
|
||||||
forward( aSides );
|
forward( aSides );
|
||||||
arc( aCorner, true );
|
miter( aCorner, true );
|
||||||
forward( aTop );
|
forward( aTop );
|
||||||
arc( aCorner, true );
|
miter( aCorner, true );
|
||||||
forward( aSides );
|
forward( aSides );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,7 +361,7 @@ SHAPE_LINE_CHAIN PNS_MEANDER_SHAPE::genMeanderShape( VECTOR2D aP, VECTOR2D aDir,
|
||||||
}
|
}
|
||||||
case MT_START:
|
case MT_START:
|
||||||
{
|
{
|
||||||
arc( cr - offset, false );
|
miter( cr - offset, false );
|
||||||
uShape( aAmpl - 2 * cr + std::abs( offset ), cr + offset, spc - 2 * cr );
|
uShape( aAmpl - 2 * cr + std::abs( offset ), cr + offset, spc - 2 * cr );
|
||||||
forward( std::min( cr - offset, cr + offset ) );
|
forward( std::min( cr - offset, cr + offset ) );
|
||||||
forward( std::abs( offset ) );
|
forward( std::abs( offset ) );
|
||||||
|
@ -351,7 +376,7 @@ SHAPE_LINE_CHAIN PNS_MEANDER_SHAPE::genMeanderShape( VECTOR2D aP, VECTOR2D aDir,
|
||||||
forward( std::min( cr - offset, cr + offset ) );
|
forward( std::min( cr - offset, cr + offset ) );
|
||||||
forward( std::abs( offset ) );
|
forward( std::abs( offset ) );
|
||||||
uShape( aAmpl - 2 * cr + std::abs( offset ), cr + offset, spc - 2 * cr );
|
uShape( aAmpl - 2 * cr + std::abs( offset ), cr + offset, spc - 2 * cr );
|
||||||
arc( cr - offset, false );
|
miter( cr - offset, false );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,9 +392,9 @@ SHAPE_LINE_CHAIN PNS_MEANDER_SHAPE::genMeanderShape( VECTOR2D aP, VECTOR2D aDir,
|
||||||
|
|
||||||
case MT_SINGLE:
|
case MT_SINGLE:
|
||||||
{
|
{
|
||||||
arc( cr - offset, false );
|
miter( cr - offset, false );
|
||||||
uShape( aAmpl - 2 * cr + std::abs( offset ), cr + offset, spc - 2 * cr );
|
uShape( aAmpl - 2 * cr + std::abs( offset ), cr + offset, spc - 2 * cr );
|
||||||
arc( cr - offset, false );
|
miter( cr - offset, false );
|
||||||
lc.Append( aP + dir_v_b + aDir.Resize ( 2 * st.m_spacing ) );
|
lc.Append( aP + dir_v_b + aDir.Resize ( 2 * st.m_spacing ) );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,12 @@ enum PNS_MEANDER_TYPE {
|
||||||
MT_EMPTY // no meander (straight line)
|
MT_EMPTY // no meander (straight line)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
///> meander corner shape
|
||||||
|
enum PNS_MEANDER_STYLE {
|
||||||
|
MEANDER_STYLE_ROUND = 1, // rounded (90 degree arc)
|
||||||
|
MEANDER_STYLE_CHAMFER // chamfered (45 degree segment)
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class PNS_MEANDER_SETTINGS
|
* Class PNS_MEANDER_SETTINGS
|
||||||
*
|
*
|
||||||
|
@ -49,12 +55,6 @@ class PNS_MEANDER_SETTINGS
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
///> meander corner shape
|
|
||||||
enum CornerType {
|
|
||||||
ROUND = 1, // rounded (90 degree arc)
|
|
||||||
CHAMFER // chamfered (45 degree segment)
|
|
||||||
};
|
|
||||||
|
|
||||||
PNS_MEANDER_SETTINGS()
|
PNS_MEANDER_SETTINGS()
|
||||||
{
|
{
|
||||||
m_minAmplitude = 100000;
|
m_minAmplitude = 100000;
|
||||||
|
@ -63,7 +63,7 @@ public:
|
||||||
m_spacing = 600000;
|
m_spacing = 600000;
|
||||||
m_targetLength = 100000000;
|
m_targetLength = 100000000;
|
||||||
m_targetSkew = 0;
|
m_targetSkew = 0;
|
||||||
m_cornerType = ROUND;
|
m_cornerStyle = MEANDER_STYLE_ROUND;
|
||||||
m_cornerRadiusPercentage = 100;
|
m_cornerRadiusPercentage = 100;
|
||||||
m_lengthTolerance = 100000;
|
m_lengthTolerance = 100000;
|
||||||
m_cornerArcSegments = 8;
|
m_cornerArcSegments = 8;
|
||||||
|
@ -80,7 +80,7 @@ public:
|
||||||
///> desired length of the tuned line/diff pair
|
///> desired length of the tuned line/diff pair
|
||||||
int m_targetLength;
|
int m_targetLength;
|
||||||
///> type of corners for the meandered line
|
///> type of corners for the meandered line
|
||||||
CornerType m_cornerType;
|
PNS_MEANDER_STYLE m_cornerStyle;
|
||||||
///> rounding percentage (0 - 100)
|
///> rounding percentage (0 - 100)
|
||||||
int m_cornerRadiusPercentage;
|
int m_cornerRadiusPercentage;
|
||||||
///> allowable tuning error
|
///> allowable tuning error
|
||||||
|
@ -325,13 +325,13 @@ private:
|
||||||
void forward( int aLength );
|
void forward( int aLength );
|
||||||
///> turns the turtle by aAngle
|
///> turns the turtle by aAngle
|
||||||
void turn( int aAngle );
|
void turn( int aAngle );
|
||||||
///> tells the turtle to draw an arc of given radius and turn direction
|
///> tells the turtle to draw a mitered corner of given radius and turn direction
|
||||||
void arc( int aRadius, bool aSide );
|
void miter( int aRadius, bool aSide );
|
||||||
///> tells the turtle to draw an U-like shape
|
///> tells the turtle to draw an U-like shape
|
||||||
void uShape( int aSides, int aCorner, int aTop );
|
void uShape( int aSides, int aCorner, int aTop );
|
||||||
|
|
||||||
///> generates a 90-degree circular arc
|
///> generates a 90-degree circular arc
|
||||||
SHAPE_LINE_CHAIN circleQuad( VECTOR2D aP, VECTOR2D aDir, bool aSide );
|
SHAPE_LINE_CHAIN makeMiterShape( VECTOR2D aP, VECTOR2D aDir, bool aSide );
|
||||||
|
|
||||||
///> reflects a point onto other side of a given segment
|
///> reflects a point onto other side of a given segment
|
||||||
VECTOR2I reflect( VECTOR2I aP, const SEG& aLine );
|
VECTOR2I reflect( VECTOR2I aP, const SEG& aLine );
|
||||||
|
|
Loading…
Reference in New Issue