From f10193490907b55019e21c5b16b77cc9c05fd877 Mon Sep 17 00:00:00 2001 From: Jon Evans Date: Sat, 25 May 2019 15:01:54 -0400 Subject: [PATCH] Report actual intersection position for crossing tracks Fixes: lp:1825588 * https://bugs.launchpad.net/kicad/+bug/1825588 --- common/geometry/trigo.cpp | 14 +++++++++----- include/trigo.h | 4 +++- pcbnew/drc_clearance_test_functions.cpp | 24 ++++++++++++++++++++---- 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/common/geometry/trigo.cpp b/common/geometry/trigo.cpp index a20e81cd01..92e1230351 100644 --- a/common/geometry/trigo.cpp +++ b/common/geometry/trigo.cpp @@ -56,7 +56,8 @@ bool IsPointOnSegment( const wxPoint& aSegStart, const wxPoint& aSegEnd, // Returns true if the segment 1 intersectd the segment 2. bool SegmentIntersectsSegment( const wxPoint &a_p1_l1, const wxPoint &a_p2_l1, - const wxPoint &a_p1_l2, const wxPoint &a_p2_l2 ) + const wxPoint &a_p1_l2, const wxPoint &a_p2_l2, + wxPoint* aIntersectionPoint ) { //We are forced to use 64bit ints because the internal units can oveflow 32bit ints when @@ -87,10 +88,13 @@ bool SegmentIntersectsSegment( const wxPoint &a_p1_l1, const wxPoint &a_p2_l1, num_a = dY_ab * dX_b - dY_b * dX_ab; num_b = dY_ab * dX_a - dY_a * dX_ab; - //We wont calculate directly the u_k of the intersection point to avoid floating point - // division but they could be calculated with: - // u_a = (float) num_a / (float) den; - // u_b = (float) num_b / (float) den; + // Only compute the intersection point if requested + if( aIntersectionPoint ) + { + *aIntersectionPoint = a_p1_l1; + aIntersectionPoint->x += KiROUND( dX_a * ( double )num_a / ( double )den ); + aIntersectionPoint->y += KiROUND( dY_a * ( double )num_b / ( double )den ); + } if( den < 0 ) { diff --git a/include/trigo.h b/include/trigo.h index e3e87e6c01..386cd29b17 100644 --- a/include/trigo.h +++ b/include/trigo.h @@ -52,11 +52,13 @@ bool IsPointOnSegment( const wxPoint& aSegStart, const wxPoint& aSegEnd, * @param a_p2_l1 The second point of the first line. * @param a_p1_l2 The first point of the second line. * @param a_p2_l2 The second point of the second line. + * @param aIntersectionPoint is filled with the intersection point if it exists * @return bool - true if the two segments defined by four points intersect. * (i.e. if the 2 segments have at least a common point) */ bool SegmentIntersectsSegment( const wxPoint &a_p1_l1, const wxPoint &a_p2_l1, - const wxPoint &a_p1_l2, const wxPoint &a_p2_l2 ); + const wxPoint &a_p1_l2, const wxPoint &a_p2_l2, + wxPoint* aIntersectionPoint = nullptr ); /* * Calculate the new point of coord coord pX, pY, diff --git a/pcbnew/drc_clearance_test_functions.cpp b/pcbnew/drc_clearance_test_functions.cpp index 952d8429fd..9af021a36b 100644 --- a/pcbnew/drc_clearance_test_functions.cpp +++ b/pcbnew/drc_clearance_test_functions.cpp @@ -606,8 +606,10 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool aTestPads, bool aTestZ if( ( segStartPoint.y < 0 ) && ( segEndPoint.y > 0 ) ) { - markers.push_back( - m_markerFactory.NewMarker( aRefSeg, track, seg, DRCE_TRACKS_CROSSING ) ); + MARKER_PCB* m = m_markerFactory.NewMarker( aRefSeg, track, seg, + DRCE_TRACKS_CROSSING ); + m->SetPosition( wxPoint( track->GetStart().x, aRefSeg->GetStart().y ) ); + markers.push_back( m ); if( !handleNewMarker() ) return false; @@ -654,8 +656,22 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool aTestPads, bool aTestZ if( !checkLine( segStartPoint, segEndPoint ) ) { - markers.push_back( - m_markerFactory.NewMarker( aRefSeg, track, seg, DRCE_ENDS_PROBLEM3 ) ); + wxPoint failurePoint; + MARKER_PCB* m; + + if( SegmentIntersectsSegment( aRefSeg->GetStart(), aRefSeg->GetEnd(), + track->GetStart(), track->GetEnd(), + &failurePoint ) ) + { + m = m_markerFactory.NewMarker( aRefSeg, track, seg, DRCE_TRACKS_CROSSING ); + m->SetPosition( failurePoint ); + } + else + { + m = m_markerFactory.NewMarker( aRefSeg, track, seg, DRCE_ENDS_PROBLEM3 ); + } + + markers.push_back( m ); if( !handleNewMarker() ) return false;