117 if( aConstraint.
HasMin() )
120 if( aConstraint.
HasMax() )
162 if( aConstraint.
HasMin() )
165 if( aConstraint.
HasMax() )
174 if( aConstraint.
HasMin() )
177 if( aConstraint.
HasMax() )
203 if( aConstraint.
HasMin() )
206 if( aConstraint.
HasMax() )
232 if( aConstraint.
HasMin() )
235 if( aConstraint.
HasMax() )
254 double base_len = aBase.
Length();
265 bool turning =
false;
266 bool started =
false;
277 double thr = (double) m.
spacing();
280 double remaining = base_len - (
m_last - aBase.
A ).EuclideanNorm();
282 auto flipInitialSide =
287 m_placer->UpdateSettings( settings );
290 auto addSingleIfFits =
302 if( fail && !singleSided )
317 if( remaining <
Settings( ).m_step )
320 if( !singleSided && remaining > 3.0 * thr )
324 for(
int i = 0; i < 2; i++ )
326 bool checkSide = ( i == 0 ) ? side : !side;
330 if( !started && checkSide != side )
364 else if( !singleSided && started )
374 else if( !turning && remaining > thr * 2.0 )
383 remaining = base_len - (
m_last - aBase.
A ).EuclideanNorm( );
385 if( remaining <
Settings( ).m_step )
443 int maxCr = std::min( maxCr1, maxCr2 );
445 wxCHECK2_MSG( maxCr >= minCr,
return maxCr,
446 wxString::Format(
"cornerRadius %d < %d amp %d spc %d w %d off %d", maxCr, minCr,
450 int optCr =
static_cast<int>(
static_cast<SEG::ecoord>(
spacing() ) * rPercent / 200 );
452 return std::clamp( optCr, minCr, maxCr );
465 return std::max( sp,
Settings().m_spacing );
484 VECTOR2D endPoint = aP + dir_u + dir_v * ( aSide ? -1.0 : 1.0 );
486 lc.
Append( (
int ) p.x, (
int ) p.y );
489 switch(
m_placer->MeanderSettings().m_cornerStyle )
493 VECTOR2I arcEnd( (
int) endPoint.
x, (
int) endPoint.
y );
513 lc.
Append( (
int ) p.x, (
int ) p.y );
514 p = aP + dir_u + (dir_v + dir_cv) * ( aSide ? -1.0 : 1.0 );
515 lc.
Append( (
int ) p.x, (
int ) p.y );
518 lc.
Append( (
int) p.x, (
int) p.y );
578 miter( aCorner,
true );
580 miter( aCorner,
true );
587 int aBaselineOffset )
590 int offset = aBaselineOffset;
601 if( 2 * cr > amplitude +
std::abs( offset ) )
602 cr = ( amplitude +
std::abs( offset ) ) / 2;
607 if( cr - offset < 0 )
612 int sCorner = cr - offset;
613 int uCorner = cr + offset;
614 int startSide = amplitude - 2 * cr +
std::abs( offset );
615 int turnSide = amplitude - cr;
616 int top = spc - 2 * cr;
620 start( &lc, aP + dir_v_b, aDir );
625 lc.
Append( aP + dir_v_b + aDir );
630 top = std::max(
top, targetBaseLen - sCorner - uCorner * 2 + offset );
632 miter( sCorner,
false );
634 forward( std::min( sCorner, uCorner ) );
640 top = std::max(
top, targetBaseLen - cr - spc );
642 start( &lc, aP - dir_u_b, aDir );
644 forward( std::min( sCorner, uCorner ) );
647 miter( sCorner,
false );
649 if( targetBaseLen >= spc + cr )
650 lc.
Append( aP + dir_v_b + aDir.
Resize( targetBaseLen ) );
652 lc.
Append( aP + dir_v_b + aDir.
Resize( 2 * spc - cr ) );
658 top = std::max(
top, targetBaseLen - uCorner * 2 + offset * 2 );
660 start( &lc, aP - dir_u_b, aDir );
669 top = std::max(
top, ( targetBaseLen - sCorner * 2 - uCorner * 2 ) / 2 );
671 miter( sCorner,
false );
673 miter( sCorner,
false );
683 SEG axis( aP, aP + aDir );
697 for(
int i =
m_meanders.size() - 1; i >= 0; i-- )
712 for(
int j = n - 1; j >= 0; j-- )
727 bool checkMode =
false;
752 bool c1 = m1.
Fit( prim1, aSeg, aP, aSide );
756 c2 =
m2.Fit( prim2, aSeg, m1.
End(), !aSide );
787 int minCornerRadius =
m_width / 2;
789 for(
int ampl = maxAmpl; ampl >= minAmpl; ampl -= st.
m_step )
963 return copy.CurrentLength();
constexpr EDA_IU_SCALE pcbIUScale
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.
Dimensions for the meandering algorithm.
int m_minAmplitude
Minimum meandering amplitude.
void SetTargetLength(long long int aOpt)
bool m_isTimeDomain
Calculate tuning in the time domain.
static const long long int LENGTH_UNCONSTRAINED
int m_cornerRadiusPercentage
Rounding percentage (0 - 100).
MEANDER_SIDE m_initialSide
Initial side when placing meanders at segment.
bool m_singleSided
Place meanders on one side.
void SetTargetLengthDelay(long long int aOpt)
static const int SKEW_UNCONSTRAINED
static const long long int DEFAULT_DELAY_TOLERANCE
MINOPTMAX< long long int > m_targetLength
Desired length of the tuned line/diff pair (this is in nm, so allow more than board width).
NETCLASS * m_netClass
The net class this meander pattern belongs to.
void SetTargetSignalLengthDelay(long long int aOpt)
void SetTargetSkew(int aOpt)
void SetTargetSignalLength(long long int aOpt)
static const long long int DEFAULT_LENGTH_TOLERANCE
int m_lengthTolerance
Allowable tuning error.
int m_step
Amplitude/spacing adjustment step.
MINOPTMAX< int > m_targetSkew
Target skew value for diff pair de-skewing.
MEANDER_STYLE m_cornerStyle
Type of corners for the meandered line.
MINOPTMAX< long long int > m_targetSignalLengthDelay
Desired overall chain propagation delay.
bool m_keepEndpoints
Keep vertices between pre, tuned and post parts of the line.
MINOPTMAX< int > m_targetSkewDelay
Target skew value for diff pair de-skewing.
int m_maxAmplitude
Maximum meandering amplitude.
long long int m_signalExtraDelay
Additional pre-existing delay contributed by other nets in the same logical chain (used when chain-le...
bool m_overrideCustomRules
MINOPTMAX< long long int > m_targetLengthDelay
Desired propagation delay of the tuned line.
void SetTargetSkewDelay(int aOpt)
static const long long int DELAY_UNCONSTRAINED
int m_lenPadToDie
Length PadToDie.
long long int m_signalExtraLength
Additional pre-existing length contributed by other nets in the same logical chain (used when chain-l...
int m_spacing
Meandering period/spacing (see dialog picture for explanation).
MINOPTMAX< long long int > m_targetSignalLength
Desired chain length (copper-only, bridging subtracted).
The geometry of a single meander.
MEANDER_TYPE m_type
The type of meander.
MEANDER_PLACER_BASE * m_placer
The placer that placed this meander.
SEG m_baseSeg
Base segment (unclipped).
MEANDER_SHAPE(MEANDER_PLACER_BASE *aPlacer, int aWidth, bool aIsDual=false)
SEG m_clippedBaseSeg
Base segment (clipped).
void SetType(MEANDER_TYPE aType)
Set the type of the meander.
int m_targetBaseLen
Minimum length of the base segment to target when resizing.
SHAPE_LINE_CHAIN genMeanderShape(const VECTOR2D &aP, const VECTOR2D &aDir, bool aSide, MEANDER_TYPE aType, int aBaselineOffset=0)
Produce a meander shape of given type.
void start(SHAPE_LINE_CHAIN *aTarget, const VECTOR2D &aWhere, const VECTOR2D &aDir)
Start turtle drawing.
void SetBaseIndex(int aIndex)
Set an auxiliary index of the segment being meandered in its original LINE.
int m_baselineOffset
Offset wrs the base segment (dual only).
VECTOR2D m_currentDir
The current turtle direction.
int m_width
Width of the line.
VECTOR2D m_currentPos
The current turtle position.
SHAPE_LINE_CHAIN m_shapes[2]
The actual shapes (0 used for single, both for dual).
long long int CurrentLength() const
bool m_side
Side (true = right).
void updateBaseSegment()
Recalculate the clipped baseline after the parameters of the meander have been changed.
SHAPE_LINE_CHAIN makeMiterShape(const VECTOR2D &aP, const VECTOR2D &aDir, bool aSide)
Generate a 90-degree circular arc.
void MakeArc(const SHAPE_ARC &aArc1, const SHAPE_ARC &aArc2=SHAPE_ARC())
Create a dummy meander shape representing an arc corner.
int m_baseIndex
Index of the meandered segment in the base line.
SHAPE_LINE_CHAIN * m_currentTarget
The line the turtle is drawing on.
bool m_dual
Dual or single line.
void Recalculate()
Recalculate the line chain representing the meander's shape.
void miter(int aRadius, bool aSide)
Tell the turtle to draw a mitered corner of given radius and turn direction.
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
Average radius of meander corners (for correction of DP meanders).
int spacing() const
Return sanitized spacing value.
int m_amplitude
Amplitude of the meander.
int cornerRadius() const
Return sanitized corner radius value.
void turn(const EDA_ANGLE &aAngle)
Turn the turtle by aAngle.
void SetBaselineOffset(int aOffset)
Set the parallel offset between the base segment and the meandered line.
void forward(int aLength)
Move turtle forward by aLength.
MEANDER_TYPE Type() const
VECTOR2I m_p0
First point of the meandered line.
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)
Tell the turtle to draw an U-like shape.
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.
VECTOR2I::extended_type ecoord
int Length() const
Return the length (this).
bool ApproxParallel(const SEG &aSeg, int aDistanceThreshold=1) const
bool Contains(const SEG &aSeg) const
SHAPE_ARC & ConstructFromStartEndAngle(const VECTOR2I &aStart, const VECTOR2I &aEnd, const EDA_ANGLE &aAngle, double aWidth=0)
Construct this arc from the given start, end and angle.
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 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 VECTOR2I & CLastPoint() const
Return the last point in the line chain.
void Mirror(const VECTOR2I &aRef, FLIP_DIRECTION aFlipDirection)
Mirror the line points about y or x (or both).
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).
constexpr 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.
MEANDER_SIDE
Initial side the meander is placed on.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
constexpr double correction
const double IU_PER_PS
Internal time units are attoseconds.
constexpr int mmToIU(double mm) const
KIBIS top(path, &reporter)
MATRIX3x3D m2(VECTOR3I{ 6, 6, 6 }, { 1, 1, 1 }, { 3, 3, 3 })
Test suite for KiCad math code.
SHAPE_ARC arc2(c.m_arc2.GenerateArc())
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
double DEG2RAD(double deg)
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D