47 double base_len = aBase.
Length();
70 double thr = (double) m.
spacing();
75 auto addSingleIfFits = [&]()
86 if( fail && !singleSided )
101 if( !singleSided && remaining > 3.0 * thr )
105 for(
int i = 0; i < 2; i++ )
107 bool checkSide = ( i == 0 ) ? side : !side;
142 else if( !singleSided && started )
152 else if( !turning && remaining > thr * 2.0 )
163 if( remaining <
Settings( ).m_step )
210 int optCr = (int64_t)
spacing() * rPercent / 200;
215 return std::clamp( optCr, minCr, maxCr );
230 return std::max( sp,
Settings().m_spacing );
249 lc.
Append( (
int ) p.
x, (
int ) p.
y );
256 VECTOR2D center = aP + dir_v * ( aSide ? -1.0 : 1.0 );
274 lc.
Append( (
int ) p.
x, ( int ) p.
y );
275 p = aP + dir_u + (dir_v + dir_cv) * ( aSide ? -1.0 : 1.0 );
276 lc.
Append( (
int ) p.
x, (
int ) p.
y );
281 p = aP + dir_u + dir_v * ( aSide ? -1.0 : 1.0 );
282 lc.
Append( (
int ) p.
x, ( int ) p.
y );
332 miter( aCorner,
true );
334 miter( aCorner,
true );
341 int aBaselineOffset )
344 int offset = aBaselineOffset;
355 if( 2 * cr > amplitude )
365 if( cr - offset < 0 )
372 int sCorner = cr - offset;
373 int uCorner = cr + offset;
374 int startSide = amplitude - 2 * cr +
std::abs( offset );
375 int turnSide = amplitude - cr;
376 int top = spc - 2 * cr;
380 start( &lc, aP + dir_v_b, aDir );
386 lc.
Append( aP + dir_v_b + aDir );
392 top = std::max( top, targetBaseLen - sCorner - uCorner * 2 + offset );
394 miter( sCorner,
false );
395 uShape( startSide, uCorner, top );
396 forward( std::min( sCorner, uCorner ) );
404 top = std::max( top, targetBaseLen - cr - spc );
406 start( &lc, aP - dir_u_b, aDir );
408 forward( std::min( sCorner, uCorner ) );
410 uShape( startSide, uCorner, top );
411 miter( sCorner,
false );
413 if( targetBaseLen >= spc + cr )
414 lc.
Append( aP + dir_v_b + aDir.
Resize( targetBaseLen ) );
416 lc.
Append( aP + dir_v_b + aDir.
Resize( 2 * spc - cr ) );
424 top = std::max( top, targetBaseLen - uCorner * 2 + offset * 2 );
426 start( &lc, aP - dir_u_b, aDir );
429 uShape( turnSide, uCorner, top );
437 top = std::max( top, ( targetBaseLen - sCorner * 2 - uCorner * 2 ) / 2 );
439 miter( sCorner,
false );
440 uShape( startSide, uCorner, top );
441 miter( sCorner,
false );
451 SEG axis( aP, aP + aDir );
462 for(
int i =
m_meanders.size() - 1; i >= 0; i-- )
477 for(
int j = n - 1; j >= 0; j-- )
492 bool checkMode =
false;
516 bool c1 = m1.
Fit( prim1, aSeg, aP, aSide );
520 c2 =
m2.Fit( prim2, aSeg, m1.
End(), !aSide );
547 for(
int ampl = maxAmpl; ampl >= minAmpl; ampl -= st.
m_step )
715 return copy.CurrentLength();
void AddMeander(MEANDER_SHAPE *aShape)
Add a new meander shape to the meandered line.
MEANDER_PLACER_BASE * m_placer
void AddCorner(const VECTOR2I &aA, const VECTOR2I &aB=VECTOR2I(0, 0))
Create a dummy meander shape representing a line corner.
void Clear()
Clear the line geometry, removing all corners and meanders.
std::vector< MEANDER_SHAPE * > m_meanders
void MeanderSegment(const SEG &aSeg, bool aSide, int aBaseIndex=0)
Fit maximum amplitude meanders on a given segment and adds to the current line.
void AddArc(const SHAPE_ARC &aArc1, const SHAPE_ARC &aArc2=SHAPE_ARC())
Create a dummy meander shape representing an arc corner.
void AddArcAndPt(const SHAPE_ARC &aArc1, const VECTOR2I &aPt2)
Create a dummy meander shape representing an arc corner.
bool CheckSelfIntersections(MEANDER_SHAPE *aShape, int aClearance)
Check if the given shape is intersecting with any other meander in the current line.
const MEANDER_SETTINGS & Settings() const
void AddPtAndArc(const VECTOR2I &aPt1, const SHAPE_ARC &aArc2)
Create a dummy meander shape representing an arc corner.
virtual bool CheckFit(MEANDER_SHAPE *aShape)
Checks if it's OK to place the shape aShape (i.e.
virtual int Clearance()
Return the clearance of the track(s) being length tuned.
virtual const MEANDER_SETTINGS & MeanderSettings() const
Return the current meandering configuration.
Dimensions for the meandering algorithm.
int m_minAmplitude
Maximum meandering amplitude.
int m_cornerRadiusPercentage
Place meanders on one side.
bool m_singleSided
Allowable tuning error.
int m_step
Length PadToDie.
MEANDER_STYLE m_cornerStyle
Rounding percentage (0 - 100).
int m_maxAmplitude
Meandering period/spacing (see dialog picture for explanation).
The geometry of a single meander.
MEANDER_TYPE m_type
The placer that placed this meander.
MEANDER_PLACER_BASE * m_placer
Dual or single line.
SEG m_baseSeg
Base segment (clipped).
SEG m_clippedBaseSeg
Side (true = right).
void SetType(MEANDER_TYPE aType)
Set the type of the meander.
int m_targetBaseLen
First point of the meandered line.
SHAPE_LINE_CHAIN genMeanderShape(const VECTOR2D &aP, const VECTOR2D &aDir, bool aSide, MEANDER_TYPE aType, int aBaselineOffset=0)
Recalculate the clipped baseline after the parameters of the meander have been changed.
void start(SHAPE_LINE_CHAIN *aTarget, const VECTOR2D &aWhere, const VECTOR2D &aDir)
Move turtle forward by aLength.
void SetBaseIndex(int aIndex)
Set an auxiliary index of the segment being meandered in its original LINE.
int m_baselineOffset
Average radius of meander corners (for correction of DP meanders).
VECTOR2D m_currentDir
The current turtle position.
int m_width
Amplitude of the meander.
VECTOR2D m_currentPos
The line the turtle is drawing on.
SHAPE_LINE_CHAIN m_shapes[2]
Index of the meandered segment in the base line.
long long int CurrentLength() const
bool m_side
The actual shapes (0 used for single, both for dual).
void updateBaseSegment()
Return sanitized corner radius value.
SHAPE_LINE_CHAIN makeMiterShape(const VECTOR2D &aP, const VECTOR2D &aDir, bool aSide)
Produce a meander shape of given type.
void MakeArc(const SHAPE_ARC &aArc1, const SHAPE_ARC &aArc2=SHAPE_ARC())
Create a dummy meander shape representing an arc corner.
int m_baseIndex
The current turtle direction.
SHAPE_LINE_CHAIN * m_currentTarget
bool m_dual
Width of the line.
void Recalculate()
Recalculate the line chain representing the meander's shape.
void miter(int aRadius, bool aSide)
Tell the turtle to draw an U-like shape.
long long int MinTunableLength() const
void Resize(int aAmpl)
Change the amplitude of the meander shape to aAmpl and recalculates the resulting line chain.
int m_meanCornerRadius
Minimum length of the base segment to target when resizing.
int spacing() const
The type of meander.
int m_amplitude
Offset wrs the base segment (dual only).
int cornerRadius() const
Return sanitized spacing value.
void turn(const EDA_ANGLE &aAngle)
Tell the turtle to draw a mitered corner of given radius and turn direction.
void SetBaselineOffset(int aOffset)
Set the parallel offset between the base segment and the meandered line.
void forward(int aLength)
Turn the turtle by aAngle.
MEANDER_TYPE Type() const
VECTOR2I m_p0
Base segment (unclipped).
const MEANDER_SETTINGS & Settings() const
void MakeEmpty()
Replace the meander with straight bypass line(s), effectively clearing it.
bool Fit(MEANDER_TYPE aType, const SEG &aSeg, const VECTOR2I &aP, bool aSide)
Attempt to fit a meander of a given type onto a segment, avoiding collisions with other board feature...
void uShape(int aSides, int aCorner, int aTop)
Generate a 90-degree circular arc.
const SHAPE_LINE_CHAIN & CLine(int aShape) const
int BaselineLength() const
const SEG & BaseSegment() const
Return the base segment the meander was fitted to.
void MakeCorner(const VECTOR2I &aP1, const VECTOR2I &aP2=VECTOR2I(0, 0))
Create a dummy meander shape representing a line corner.
int Length() const
Return the length (this).
bool ApproxParallel(const SEG &aSeg, int aDistanceThreshold=1) const
bool Contains(const SEG &aSeg) const
VECTOR2I LineProject(const VECTOR2I &aP) const
Compute the perpendicular projection point of aP on a line passing through ends of the segment.
const VECTOR2I & GetP1() const
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
virtual bool Collide(const VECTOR2I &aP, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const override
Check if point aP lies closer to us than aClearance.
void Clear()
Remove all points from the line chain.
void Mirror(bool aX=true, bool aY=false, const VECTOR2I &aRef={ 0, 0 })
Mirror the line points about y or x (or both).
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
int SegmentCount() const
Return the number of segments in this line chain.
const SEG CSegment(int aIndex) const
Return a constant copy of the aIndex segment in the line chain.
long long int Length() const
Return length of the line chain in Euclidean metric.
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
VECTOR2< T > Perpendicular() const
Compute the perpendicular vector.
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
static constexpr EDA_ANGLE & ANGLE_90
Push and Shove diff pair dimensions (gap) settings dialog.
MEANDER_TYPE
Shapes of available meanders.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
constexpr double correction
MATRIX3x3D m2(VECTOR3I{ 6, 6, 6 }, { 1, 1, 1 }, { 3, 3, 3 })
Test suite for KiCad math code.
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
double EuclideanNorm(const VECTOR2I &vector)