49 std::vector<PCB_TRACK*>* buffer;
53 buffer =
new std::vector<PCB_TRACK*>;
58 buffer = (*item).second;
61 buffer->push_back( aTrack );
70 return via->GetWidth( aLayer );
75 return std::min(
pad->GetSize( aLayer ).x,
pad->GetSize( aLayer ).y );
95 &&
pad->GetSize( aLayer ).x
96 ==
pad->GetSize( aLayer ).y );
125 if( zone->IsTeardropArea() )
129 if( !zone->IsOnLayer( layer ) )
132 if( zone->GetNetCode() != aTrack->
GetNetCode() )
136 if( !zone->HasFilledPolysForLayer( layer ) )
139 std::shared_ptr<SHAPE_POLY_SET> fill = zone->GetFilledPolysList( layer );
141 if( !fill || fill->IsEmpty() )
149 if( !fill->Contains( padPos ) )
153 if( !fill->Contains( aTrack->
GetStart() ) && !fill->Contains( aTrack->
GetEnd() ) )
159 PAD*
pad =
static_cast<PAD*
>( aPadOrVia );
180 return std::numeric_limits<int>::max();
183 double len =
delta.EuclideanNorm();
186 return std::numeric_limits<int>::max();
188 int maxError =
m_board->GetDesignSettings().m_MaxError;
192 if(
IsRound( aOther, aLayer ) )
199 wxCHECK_MSG( aOther->
Type() ==
PCB_PAD_T, 0, wxT(
"Expected non-round item to be PAD" ) );
200 static_cast<PAD*
>( aOther )->TransformShapeToPolygon( shapebuffer, aLayer, 0, maxError,
215 for(
int ii = 0; ii < shapebuffer.
OutlineCount(); ++ii )
221 for(
int jj = 0; jj < shapebuffer.
HoleCount( ii ); ++jj )
231 return std::numeric_limits<int>::max();
235 std::vector<double> proj;
236 proj.reserve( pts.size() );
239 proj.push_back( ( hit.p - extStart ).Dot( dir ) );
241 std::sort( proj.begin(), proj.end() );
243 double insideProj = (
VECTOR2D( aInsidePoint ) -
VECTOR2D( extStart ) ).Dot( dir );
245 for(
size_t ii = 0; ii + 1 < proj.size(); ++ii )
248 KiROUND( dir.
y * ( proj[ii] + proj[ii + 1] ) / 2 ) );
250 if( !shapebuffer.
Contains( spanMid ) )
253 if( insideProj >= proj[ii] && insideProj <= proj[ii + 1] )
254 return KiROUND( proj[ii + 1] - proj[ii] );
258 return std::numeric_limits<int>::max();
272 return trackItem != aTrackRef;
277 PCB_TRACK* curr_track = static_cast<PCB_TRACK*>( trackItem );
280 if( EDA_ITEM_FLAGS match = curr_track->IsPointOnEnds( aEndPoint, m_tolerance ) )
287 double previous_len = candidate->GetLength();
288 double curr_len = curr_track->GetLength();
290 if( previous_len >= curr_len )
295 candidate = curr_track;
326 std::vector<VECTOR2I>& aPoly,
328 int aTrackHalfWidth,
const VECTOR2D& aTrackDir,
330 std::vector<VECTOR2I>& pts )
const
332 int maxError =
m_board->GetDesignSettings().m_MaxError;
352 double minVpercent = double( aTrackHalfWidth ) /
radius;
353 double weaken = (Vpercent - minVpercent) / ( 1 - minVpercent ) /
radius;
365 vecC = pts[2] - aOtherPos;
375 vecE = pts[4] - aOtherPos;
378 double biasBC = 0.5 *
SEG( pts[1], pts[2] ).
Length();
379 double biasAE = 0.5 *
SEG( pts[4], pts[0] ).
Length();
382 pts[2].y + vecC.
x * biasBC * weaken );
384 pts[4].y - vecE.
x * biasAE * weaken );
386 VECTOR2I tangentB =
VECTOR2I( pts[1].x - aTrackDir.
x * biasBC, pts[1].y - aTrackDir.
y * biasBC );
387 VECTOR2I tangentA =
VECTOR2I( pts[0].x - aTrackDir.
x * biasAE, pts[0].y - aTrackDir.
y * biasAE );
389 std::vector<VECTOR2I> curve_pts;
393 aPoly.push_back( corner );
395 aPoly.push_back( pts[3] );
401 aPoly.push_back( corner );
421 VECTOR2I radial = aAnchor - aCornerCenter;
433 int64_t dot1 =
static_cast<int64_t
>( tangent1.
x ) * aDesiredDir.
x
434 +
static_cast<int64_t
>( tangent1.
y ) * aDesiredDir.
y;
435 int64_t dot2 =
static_cast<int64_t
>( tangent2.
x ) * aDesiredDir.
x
436 +
static_cast<int64_t
>( tangent2.
y ) * aDesiredDir.
y;
438 VECTOR2I tangent = ( dot1 > dot2 ) ? tangent1 : tangent2;
460 VECTOR2I localPt = aPoint - aPadPos;
463 int halfW = aPadSize.
x / 2;
464 int halfH = aPadSize.
y / 2;
468 int radius = std::min( halfW, halfH );
469 bool isHorizontal = halfW > halfH;
474 int centerOffset = halfW -
radius;
477 if(
std::abs( localPt.
x ) <= centerOffset )
481 int centerX = ( localPt.
x > 0 ) ? centerOffset : -centerOffset;
482 aArcCenter =
VECTOR2I( centerX, 0 );
487 int centerOffset = halfH -
radius;
490 if(
std::abs( localPt.
y ) <= centerOffset )
494 int centerY = ( localPt.
y > 0 ) ? centerOffset : -centerOffset;
495 aArcCenter =
VECTOR2I( 0, centerY );
500 aArcCenter += aPadPos;
519 const VECTOR2I& aPadSize,
int aCornerRadius,
523 VECTOR2I localPt = aPoint - aPadPos;
527 int halfW = aPadSize.
x / 2;
528 int halfH = aPadSize.
y / 2;
529 int innerHalfW = halfW - aCornerRadius;
530 int innerHalfH = halfH - aCornerRadius;
533 bool inCornerX =
std::abs( localPt.
x ) > innerHalfW;
534 bool inCornerY =
std::abs( localPt.
y ) > innerHalfH;
536 if( !inCornerX || !inCornerY )
540 int cornerX = ( localPt.
x > 0 ) ? innerHalfW : -innerHalfW;
541 int cornerY = ( localPt.
y > 0 ) ? innerHalfH : -innerHalfH;
543 aCornerCenter =
VECTOR2I( cornerX, cornerY );
547 aCornerCenter += aPadPos;
559 std::vector<VECTOR2I>& aPoly,
int aTdWidth,
561 std::vector<VECTOR2I>& aPts,
567 int maxError =
m_board->GetDesignSettings().m_MaxError;
575 VECTOR2I side1( aPts[2] - aPts[1] );
577 VECTOR2I side2( aPts[4] - aPts[0] );
579 VECTOR2I trackDir( aIntersection - ( aPts[0] + aPts[1] ) / 2 );
582 bool isRoundRect =
false;
584 int cornerRadius = 0;
596 cornerRadius =
pad->GetRoundRectCornerRadius( aLayer );
597 padSize =
pad->GetSize( aLayer );
598 padRotation =
pad->GetOrientation();
603 padSize =
pad->GetSize( aLayer );
604 padRotation =
pad->GetOrientation();
608 std::vector<VECTOR2I> curve_pts;
618 ctrl2 = ( aPts[2] + aIntersection ) / 2;
620 if( isRoundRect && cornerRadius > 0 )
625 padRotation, cornerCenter ) )
636 if(
isPointOnOvalEnd( aPts[2], aOtherPos, padSize, padRotation, arcCenter ) )
647 aPoly.push_back( corner );
649 aPoly.push_back( aPts[3] );
655 ctrl1 = ( aPts[4] + aIntersection ) / 2;
657 if( isRoundRect && cornerRadius > 0 )
662 padRotation, cornerCenter ) )
673 if(
isPointOnOvalEnd( aPts[4], aOtherPos, padSize, padRotation, arcCenter ) )
686 aPoly.push_back( corner );
692 std::vector<VECTOR2I>& aPts )
const
694 int maxError =
m_board->GetDesignSettings().m_MaxError;
725 wxCHECK_MSG( aItem->
Type() ==
PCB_PAD_T,
false, wxT(
"Expected non-round item to be PAD" ) );
731 pad->TransformShapeToPolygon( c_buffer, aLayer, 0, maxError,
ERROR_INSIDE );
738 int halfsize = std::min( aParams.
m_TdMaxWidth, preferred_width )/2;
743 VECTOR2I ref_on_track = ( aPts[0] + aPts[1] ) / 2;
744 VECTOR2I teardrop_axis( aPts[3] - ref_on_track );
756 clipping_rect.
Append( 0, - halfsize );
757 clipping_rect.
Append( 0, halfsize );
758 clipping_rect.
Append( len, halfsize );
759 clipping_rect.
Append( len, - halfsize );
761 clipping_rect.
Rotate( -orient );
762 clipping_rect.
Move( ref_on_track );
778 std::vector<VECTOR2I> points = padpoly.
CPoints();
780 std::vector<VECTOR2I> initialPoints;
781 initialPoints.push_back( aPts[0] );
782 initialPoints.push_back( aPts[1] );
785 initialPoints.emplace_back( pt.x, pt.y );
787 std::vector<VECTOR2I> hull;
794 int found_start = -1;
800 for(
unsigned ii = 0, jj = 0; jj < hull.size(); ii++, jj++ )
802 unsigned next = ii+ 1;
804 if(
next >= hull.size() )
810 prev = hull.size()-1;
812 if( hull[ii] == start )
815 if( hull[
next] != pend )
823 if( hull[ii] == pend )
825 if( hull[
next] != start )
834 if( found_start < 0 )
836 int ii = found_end-1;
846 int ii = found_start-1;
863 double area1 = dummy1.
Area();
865 std::swap( aPts[2], aPts[4] );
867 double area2 = dummy2.
Area();
870 std::swap( aPts[2], aPts[4] );
880 int* aEffectiveTeardropLen )
const
887 int maxError =
m_board->GetDesignSettings().m_MaxError;
893 targetLength = std::min( aParams.
m_TdMaxLen, targetLength );
897 bool need_swap =
false;
901 if( !aOther->
HitTest( start, 0 ) )
903 std::swap( start,
end );
915 wxCHECK_MSG( aOther->
Type() ==
PCB_PAD_T,
false, wxT(
"Expected non-round item to be PAD" ) );
916 static_cast<PAD*
>( aOther )->TransformShapeToPolygon( shapebuffer, aTrack->
GetLayer(), 0,
936 pt_count = outline.
Intersect( poly, pts );
948 aIntersection = pts[0].p;
949 start = aIntersection;
953 actualTdLen = std::min( targetLength,
SEG( start,
end ).Length() );
962 while( actualTdLen + consumed < targetLength )
968 if( connected_track ==
nullptr )
975 constexpr double kMinCosForTwoSegmentExtension = 0.5;
988 - connected_track->
GetEnd() );
991 double cosAngle = firstDir.
x * secondDir.
x + firstDir.
y * secondDir.
y;
993 if( cosAngle < kMinCosForTwoSegmentExtension )
996 consumed += actualTdLen;
998 actualTdLen = std::min( targetLength-consumed,
int( connected_track->
GetLength() ) );
999 aTrack = connected_track;
1001 start = connected_track->
GetStart();
1006 std::swap( start,
end );
1040 for(
int ii = poly.
PointCount()-1; ii >= 0 ; ii-- )
1042 int dist_from_start = ( poly.
CPoint( ii ) - start ).EuclideanNorm();
1046 if( dist_from_start < actualTdLen || ii == 0 )
1048 start = poly.
CPoint( ii );
1057 actualTdLen -= (start - ref_lenght_point).EuclideanNorm();
1060 if( actualTdLen < 0 )
1063 actualTdLen = std::min( actualTdLen, (
end - start).EuclideanNorm() );
1075 aStartPoint = start;
1078 *aEffectiveTeardropLen = actualTdLen;
1084 std::vector<VECTOR2I>& aCorners,
PCB_TRACK* aTrack,
1117 bool twoSegments = ( aTrack != originalTrack );
1125 if( twoSegments && start != intersection )
1129 int track_halfwidth = aTrack->
GetWidth() / 2;
1130 VECTOR2I pointB = start +
VECTOR2I( vecT.
x * track_stub_len + vecT.
y * track_halfwidth,
1131 vecT.
y * track_stub_len - vecT.
x * track_halfwidth );
1132 VECTOR2I pointA = start +
VECTOR2I( vecT.
x * track_stub_len - vecT.
y * track_halfwidth,
1133 vecT.
y * track_stub_len + vecT.
x * track_halfwidth );
1139 if( !
IsRound( aOther, layer ) )
1143 if(
pad->HitTest( pointA, 0, layer ) )
1146 if(
pad->HitTest( pointB, 0, layer ) )
1154 int padRadius =
GetWidth( aOther, layer ) / 2;
1156 double projOnTrack = -( intToPad.
x * vecVia.
x + intToPad.
y * vecVia.
y );
1164 double effectiveDist = isCustomPad ?
static_cast<double>( padRadius )
1165 : std::max( projOnTrack,
static_cast<double>( padRadius ) );
1172 int maxError =
m_board->GetDesignSettings().m_MaxError;
1174 pad->TransformShapeToPolygon( padPoly, layer, 0, maxError,
ERROR_INSIDE );
1182 double reach = effectiveDist + 2.0 *
pad->GetBoundingRadius() + offset;
1194 padOutline.
Intersect(
SEG( intersection, rayEnd ), hits );
1196 for(
int jj = 0; jj < padPoly.
HoleCount( ii ); ++jj )
1204 std::vector<double> crossings;
1205 crossings.reserve( hits.size() );
1210 double d = ( hit.p - intersection ).EuclideanNorm();
1213 crossings.push_back( d );
1216 std::sort( crossings.begin(), crossings.end() );
1220 double exitEdge = 0;
1222 for(
double d : crossings )
1225 KiROUND( -vecVia.
y * ( d + offset ) ) );
1236 effectiveDist = std::min( effectiveDist, std::max( 0.0, exitEdge - 2.0 * offset ) );
1247 double R =
static_cast<double>( padRadius );
1248 double cx = intToPad.
x;
1249 double cy = intToPad.
y;
1250 double distCenterSq = cx * cx + cy * cy;
1255 double disc = projOnTrack * projOnTrack - ( distCenterSq - R * R );
1259 double farEdge = projOnTrack + std::sqrt( disc );
1260 double maxAllowed = std::max( 0.0, farEdge - 2.0 * offset );
1262 if( effectiveDist > maxAllowed )
1263 effectiveDist = maxAllowed;
1268 KiROUND( -vecVia.
y * ( effectiveDist + offset ) ) );
1275 VECTOR2I junctionB_seg2, junctionB_seg1, junctionA_seg2, junctionA_seg1;
1280 KiROUND( -vecT.
x * track_halfwidth ) );
1282 KiROUND( vecT.
x * track_halfwidth ) );
1284 KiROUND( -vecVia.
x * track_halfwidth ) );
1286 KiROUND( vecVia.
x * track_halfwidth ) );
1292 bool skipJunctionA =
false;
1293 bool skipJunctionB =
false;
1299 skipJunctionA = ( transA.
x * anchorDirA.
x + transA.
y * anchorDirA.
y ) < 0;
1303 skipJunctionB = ( transB.
x * anchorDirB.
x + transB.
y * anchorDirB.
y ) < 0;
1306 VECTOR2I anchorA = twoSegments ? junctionA_seg1 : pointA;
1307 VECTOR2I anchorB = twoSegments ? junctionB_seg1 : pointB;
1309 std::vector<VECTOR2I> pts = { anchorA, anchorB, pointC, pointD, pointE };
1316 if(
IsRound( aOther, layer ) )
1322 double perpDistToCenter = padOffset.
x * perpVia.
x + padOffset.
y * perpVia.
y;
1325 if(
std::abs( perpDistToCenter ) > padRadius * 0.1 )
1327 double d =
std::abs( perpDistToCenter );
1333 double maxSymmetric =
static_cast<double>( padRadius ) - d;
1337 int maxHalfWidth = preferred_width / 2;
1340 maxHalfWidth = std::min( maxHalfWidth, aParams.
m_TdMaxWidth / 2 );
1342 double symHalfWidth = std::min( maxSymmetric,
1343 static_cast<double>( maxHalfWidth ) );
1345 if( symHalfWidth > track_halfwidth )
1348 double R =
static_cast<double>( padRadius );
1354 auto findCircleLineIntersection =
1357 double projAlongTrack = padOffset.
x * vecVia.
x
1358 + padOffset.
y * vecVia.
y;
1360 + vecVia * projAlongTrack
1361 + perpVia * perpDist;
1364 double b_coeff = oc.
x * vecVia.
x + oc.
y * vecVia.
y;
1365 double c_coeff = oc.
x * oc.
x + oc.
y * oc.
y - R * R;
1366 double disc = b_coeff * b_coeff - c_coeff;
1372 double sqrtDisc = std::sqrt( disc );
1373 double t1 = -b_coeff - sqrtDisc;
1374 double t2 = -b_coeff + sqrtDisc;
1377 VECTOR2D p1 = lineOrigin + vecVia * t1;
1378 VECTOR2D p2 = lineOrigin + vecVia * t2;
1381 if( ( p1 - intPt ).EuclideanNorm()
1382 < ( p2 - intPt ).EuclideanNorm() )
1397 pts[2] = findCircleLineIntersection( -symHalfWidth );
1398 pts[4] = findCircleLineIntersection( symHalfWidth );
1408 aCorners.push_back( pointA );
1409 aCorners.push_back( pointB );
1411 if( !skipJunctionB )
1412 aCorners.push_back( junctionB_seg2 );
1414 aCorners.push_back( pts[1] );
1415 aCorners.push_back( pts[2] );
1416 aCorners.push_back( pts[3] );
1417 aCorners.push_back( pts[4] );
1418 aCorners.push_back( pts[0] );
1420 if( !skipJunctionA )
1421 aCorners.push_back( junctionA_seg2 );
1425 aCorners = std::move( pts );
1432 if(
IsRound( aOther, layer ) )
1436 std::vector<VECTOR2I> curvePoly;
1438 vecVia, aOther, aOtherPos, pts );
1440 aCorners.push_back( pointB );
1442 if( !skipJunctionB )
1443 aCorners.push_back( junctionB_seg2 );
1445 for(
const VECTOR2I& pt : curvePoly )
1446 aCorners.push_back( pt );
1448 if( !skipJunctionA )
1449 aCorners.push_back( junctionA_seg2 );
1451 aCorners.push_back( pointA );
1456 vecT, aOther, aOtherPos, pts );
1468 std::vector<VECTOR2I> curvePoly;
1470 intersection, aOther, aOtherPos, layer );
1472 aCorners.push_back( pointB );
1474 if( !skipJunctionB )
1475 aCorners.push_back( junctionB_seg2 );
1477 for(
const VECTOR2I& pt : curvePoly )
1478 aCorners.push_back( pt );
1480 if( !skipJunctionA )
1481 aCorners.push_back( junctionA_seg2 );
1483 aCorners.push_back( pointA );
1488 intersection, aOther, aOtherPos, layer );
constexpr EDA_IU_SCALE pcbIUScale
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Bezier curves to polygon converter.
void GetPoly(std::vector< VECTOR2I > &aOutput, int aMaxError=10)
Convert a Bezier curve to a polygon.
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
ecoord_type Diagonal() const
Return the length of the diagonal of the rectangle.
virtual VECTOR2I GetPosition() const
KICAD_T Type() const
Returns the type of object.
virtual bool HitTest(const VECTOR2I &aPosition, int aAccuracy=0) const
Test if aPosition is inside or on the boundary of this item.
const VECTOR2I & GetMid() const
virtual double GetLength() const
Get the length of the track using the hypotenuse calculation.
const VECTOR2I & GetStart() const
const VECTOR2I & GetEnd() const
virtual int GetWidth() const
int Length() const
Return the length (this).
const SHAPE_LINE_CHAIN ConvertToPolyline(int aMaxError=DefaultAccuracyForPCB(), int *aActualError=nullptr) const
Construct a SHAPE_LINE_CHAIN of segments from a given arc.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
int Intersect(const SEG &aSeg, INTERSECTIONS &aIp) const
Find all intersection points between our line chain and the segment aSeg.
int PointCount() const
Return the number of points (vertices) in this line chain.
double Area(bool aAbsolute=true) const
Return the area of this chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
std::vector< INTERSECTION > INTERSECTIONS
const std::vector< VECTOR2I > & CPoints() const
Represent a set of closed polygons.
void Rotate(const EDA_ANGLE &aAngle, const VECTOR2I &aCenter={ 0, 0 }) override
Rotate all vertices by a given angle.
int HoleCount(int aOutline) const
Returns the number of holes in a given outline.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
SHAPE_LINE_CHAIN & Hole(int aOutline, int aHole)
Return the reference to aHole-th hole in the aIndex-th outline.
int NewOutline()
Creates a new empty polygon in the set and returns its index.
void BooleanIntersection(const SHAPE_POLY_SET &b)
Perform boolean polyset intersection.
int OutlineCount() const
Return the number of outlines in the set.
void Move(const VECTOR2I &aVector) override
bool Contains(const VECTOR2I &aP, int aSubpolyIndex=-1, int aAccuracy=0, bool aUseBBoxCaches=false) const
Return true if a given subpolygon contains the point aP.
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
static bool IsRound(BOARD_ITEM *aItem, PCB_LAYER_ID aLayer)
bool computeAnchorPoints(const TEARDROP_PARAMETERS &aParams, PCB_LAYER_ID aLayer, BOARD_ITEM *aItem, const VECTOR2I &aPos, std::vector< VECTOR2I > &aPts) const
Compute the 2 points on pad/via of the teardrop shape.
static int GetWidth(BOARD_ITEM *aItem, PCB_LAYER_ID aLayer)
bool computeTeardropPolygon(const TEARDROP_PARAMETERS &aParams, std::vector< VECTOR2I > &aCorners, PCB_TRACK *aTrack, BOARD_ITEM *aOther, const VECTOR2I &aOtherPos) const
Compute all teardrop points of the polygon shape.
void computeCurvedForRectShape(const TEARDROP_PARAMETERS &aParams, std::vector< VECTOR2I > &aPoly, int aTdWidth, int aTrackHalfWidth, std::vector< VECTOR2I > &aPts, const VECTOR2I &aIntersection, BOARD_ITEM *aOther, const VECTOR2I &aOtherPos, PCB_LAYER_ID aLayer) const
Compute the curve part points for teardrops connected to a rectangular/polygonal shape The Bezier cur...
void computeCurvedForRoundShape(const TEARDROP_PARAMETERS &aParams, std::vector< VECTOR2I > &aPoly, PCB_LAYER_ID aLayer, int aTrackHalfWidth, const VECTOR2D &aTrackDir, BOARD_ITEM *aOther, const VECTOR2I &aOtherPos, std::vector< VECTOR2I > &aPts) const
Compute the curve part points for teardrops connected to a round shape The Bezier curve control point...
PCB_TRACK * findTouchingTrack(EDA_ITEM_FLAGS &aMatchType, PCB_TRACK *aTrackRef, const VECTOR2I &aEndPoint) const
Find a track connected to the end of another track.
TRACK_BUFFER m_trackLookupList
bool areItemsInSameZone(BOARD_ITEM *aPadOrVia, PCB_TRACK *aTrack) const
friend class TEARDROP_PARAMETERS
int computeChordThroughShape(PCB_TRACK *aTrack, BOARD_ITEM *aOther, PCB_LAYER_ID aLayer, const VECTOR2I &aInsidePoint) const
Return the centerline chord length through aOther's copper span at aInsidePoint.
bool findAnchorPointsOnTrack(const TEARDROP_PARAMETERS &aParams, VECTOR2I &aStartPoint, VECTOR2I &aEndPoint, VECTOR2I &aIntersection, PCB_TRACK *&aTrack, BOARD_ITEM *aOther, const VECTOR2I &aOtherPos, int *aEffectiveTeardropLen) const
double m_BestWidthRatio
The height of a teardrop as ratio between height and size of pad/via.
int m_TdMaxLen
max allowed length for teardrops in IU. <= 0 to disable
bool m_AllowUseTwoTracks
True to create teardrops using 2 track segments if the first in too small.
int m_TdMaxWidth
max allowed height for teardrops in IU. <= 0 to disable
double m_BestLengthRatio
The length of a teardrop as ratio between length and size of pad/via.
bool m_CurvedEdges
True if the teardrop should be curved.
int idxFromLayNet(int aLayer, int aNetcode) const
void AddTrack(PCB_TRACK *aTrack, int aLayer, int aNetcode)
Add a track in buffer, in space grouping tracks having the same netcode and the same layer.
std::map< int, std::vector< PCB_TRACK * > * > m_map_tracks
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
Handle a list of polygons defining a copper zone.
void TransformCircleToPolygon(SHAPE_LINE_CHAIN &aBuffer, const VECTOR2I &aCenter, int aRadius, int aError, ERROR_LOC aErrorLoc, int aMinSegCount=0)
Convert a circle to a polygon, using multiple straight lines.
void BuildConvexHull(std::vector< VECTOR2I > &aResult, const std::vector< VECTOR2I > &aPoly)
Calculate the convex hull of a list of points in counter-clockwise order.
std::uint32_t EDA_ITEM_FLAGS
#define STARTPOINT
When a line is selected, these flags indicate which.
PCB_LAYER_ID
A quick note on layer IDs:
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
PAD_SHAPE
The set of pad shapes, used with PAD::{Set,Get}Shape()
Represent an intersection between two line segments.
static bool isPointOnRoundedCorner(const VECTOR2I &aPoint, const VECTOR2I &aPadPos, const VECTOR2I &aPadSize, int aCornerRadius, const EDA_ANGLE &aRotation, VECTOR2I &aCornerCenter)
Check if a point is within a rounded corner region of a rounded rectangle pad.
static bool isPointOnOvalEnd(const VECTOR2I &aPoint, const VECTOR2I &aPadPos, const VECTOR2I &aPadSize, const EDA_ANGLE &aRotation, VECTOR2I &aArcCenter)
Check if a point is on the curved (semicircular) end of an oval pad.
static VECTOR2D NormalizeVector(const VECTOR2I &aVector)
static VECTOR2I computeCornerTangentControlPoint(const VECTOR2I &aAnchor, const VECTOR2I &aCornerCenter, double aBias, const VECTOR2I &aDesiredDir)
Helper to compute a control point for a teardrop anchor on a rounded rectangle corner.
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.
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
@ PCB_PAD_T
class PAD, a pad in a footprint
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D
@ NONE
Pads are not covered.