Report actual intersection position for crossing tracks

Fixes: lp:1825588
* https://bugs.launchpad.net/kicad/+bug/1825588

(cherry picked from commit f101934909)
This commit is contained in:
Jon Evans 2019-05-25 15:01:54 -04:00
parent 549b76739e
commit e156e4509c
3 changed files with 32 additions and 10 deletions

View File

@ -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 )
{

View File

@ -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,

View File

@ -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;