teardrops: calculate better points on track for track arc.

Previously, a reference point to calculate teardrop length was calculated
using a track segment. It can create significant position error with track arcs.
Now a arc is used to find this reference point.
This commit is contained in:
jean-pierre charras 2024-02-23 11:36:14 +01:00
parent 2194f99341
commit ef6a5b6252
1 changed files with 19 additions and 5 deletions

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2021 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2021 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -555,8 +555,9 @@ bool TEARDROP_MANAGER::findAnchorPointsOnTrack( const TEARDROP_PARAMETERS& aPara
int actualTdLen; int actualTdLen;
bool need_swap = false; // true if the start and end points of the current track are swapped bool need_swap = false; // true if the start and end points of the current track are swapped
// ensure that start is at the via/pad end // aTrack is expected to have one end inside the via/pad and the other end outside
if( SEG( end, aOtherPos ).Length() < radius ) // so ensure the start point is inside the via/pad
if( !aOther->HitTest( start, 0 ) )
{ {
std::swap( start, end ); std::swap( start, end );
need_swap = true; need_swap = true;
@ -580,7 +581,20 @@ bool TEARDROP_MANAGER::findAnchorPointsOnTrack( const TEARDROP_PARAMETERS& aPara
// Search the intersection point between the pad/via shape and the current track // Search the intersection point between the pad/via shape and the current track
// This this the starting point to define the teardrop length // This this the starting point to define the teardrop length
SHAPE_LINE_CHAIN::INTERSECTIONS pts; SHAPE_LINE_CHAIN::INTERSECTIONS pts;
int pt_count = outline.Intersect( SEG( start, end ), pts ); int pt_count;
if( aTrack->Type() == PCB_ARC_T )
{
// To find the starting point we convert the arc to a polyline
// and compute the intersection point with the pad/via shape
SHAPE_ARC arc( aTrack->GetStart(), static_cast<PCB_ARC*>( aTrack )->GetMid(),
aTrack->GetEnd(), aTrack->GetWidth() );
SHAPE_LINE_CHAIN poly = arc.ConvertToPolyline();
pt_count = outline.Intersect( poly, pts );
}
else
pt_count = outline.Intersect( SEG( start, end ), pts );
// Ensure a intersection point was found, otherwise we cannot built the teardrop // Ensure a intersection point was found, otherwise we cannot built the teardrop
// using this track (it is fully outside or inside the pad/via shape) // using this track (it is fully outside or inside the pad/via shape)
@ -636,7 +650,7 @@ bool TEARDROP_MANAGER::findAnchorPointsOnTrack( const TEARDROP_PARAMETERS& aPara
if( aTrack->Type() == PCB_ARC_T ) if( aTrack->Type() == PCB_ARC_T )
{ {
// To find the best start and end points to build the teardrop shape, we convert // To find the best start and end points to build the teardrop shape, we convert
// the arc to segments, and search for the segment havig its start point at a dist // the arc to segments, and search for the segment having its start point at a dist
// < actualTdLen, and its end point at adist > actualTdLen: // < actualTdLen, and its end point at adist > actualTdLen:
SHAPE_ARC arc( aTrack->GetStart(), static_cast<PCB_ARC*>( aTrack )->GetMid(), SHAPE_ARC arc( aTrack->GetStart(), static_cast<PCB_ARC*>( aTrack )->GetMid(),
aTrack->GetEnd(), aTrack->GetWidth() ); aTrack->GetEnd(), aTrack->GetWidth() );