← Back to team overview

kicad-developers team mailing list archive

[PATCH] Improve eeschema wire merging

 

​Currently​, if you draw a line _over_ another line, eeschema will make a
junction unless you make the new line exactly on the endpoint of the old
line.

The attached patch fixes this by allowing line merges of arbitrary
overlapping segments.  It also speeds up the merge (trivially) by removing
the atan2() calls.

-Seth
From 4c25be81ec64391cc90378c616be8836377e7c64 Mon Sep 17 00:00:00 2001
From: Seth Hillbrand <hillbrand@xxxxxxxxxxx>
Date: Fri, 6 Oct 2017 10:42:55 -0700
Subject: [PATCH 1/1] Eeschema: Improve performance and merge overlapping
 segments

---
 eeschema/sch_line.cpp | 56 +++++++++++++++++++++++++++++++++------------------
 1 file changed, 36 insertions(+), 20 deletions(-)

diff --git a/eeschema/sch_line.cpp b/eeschema/sch_line.cpp
index 48c3cb397..cac1cb91d 100644
--- a/eeschema/sch_line.cpp
+++ b/eeschema/sch_line.cpp
@@ -273,12 +273,36 @@ void SCH_LINE::Rotate( wxPoint aPosition )
  */
 bool SCH_LINE::MergeOverlap( SCH_LINE* aLine )
 {
+    SCH_LINE *leftmost, *rightmost;
     wxCHECK_MSG( aLine != NULL && aLine->Type() == SCH_LINE_T, false,
                  wxT( "Cannot test line segment for overlap." ) );
 
     if( this == aLine || GetLayer() != aLine->GetLayer() )
         return false;
 
+    auto less = []( const wxPoint& lhs, const wxPoint& rhs ) -> bool
+    {
+        if( lhs.x == rhs.x )
+            return lhs.y < rhs.y;
+        return lhs.x < rhs.x;
+    };
+
+    if( m_start != std::min( { m_start, m_end }, less ) )
+        std::swap( m_start, m_end );
+    if( aLine->m_start != std::min( { aLine->m_start, aLine->m_end }, less ) )
+        std::swap( aLine->m_start, aLine->m_end );
+
+    if( less( m_start, aLine->m_start ) )
+    {
+        leftmost = this;
+        rightmost = aLine;
+    }
+    else
+    {
+        leftmost = aLine;
+        rightmost = this;
+    }
+
     // Search for a common end:
     if( m_start == aLine->m_start )
     {
@@ -296,8 +320,9 @@ bool SCH_LINE::MergeOverlap( SCH_LINE* aLine )
     }
     else if( m_end != aLine->m_start )
     {
-        // No common end point, segments cannot be merged.
-        return false;
+        // No common end point, check for maybe overlapping
+        if( less ( leftmost->m_end, rightmost->m_start ) )
+            return false;
     }
 
     bool colinear = false;
@@ -319,12 +344,13 @@ bool SCH_LINE::MergeOverlap( SCH_LINE* aLine )
     }
     else
     {
-        if( atan2( (double) ( m_start.x - m_end.x ), (double) ( m_start.y - m_end.y ) )
-            == atan2( (double) ( aLine->m_start.x - aLine->m_end.x ),
-                      (double) ( aLine->m_start.y - aLine->m_end.y ) ) )
-        {
-            colinear = true;
-        }
+        int dx = leftmost->m_end.x - leftmost->m_start.x;
+        int dy = leftmost->m_end.y - leftmost->m_start.y;
+
+        colinear = ( ( ( rightmost->m_start.y - leftmost->m_start.y ) * dx ==
+                ( rightmost->m_start.x - leftmost->m_start.x ) * dy ) &&
+            ( ( rightmost->m_end.y - leftmost->m_start.y ) * dx ==
+                ( rightmost->m_end.x - leftmost->m_start.x ) * dy ) );
     }
 
     // Make a segment which merge the 2 segments
@@ -333,18 +359,8 @@ bool SCH_LINE::MergeOverlap( SCH_LINE* aLine )
     // for horizontal segments the uppermost and the lowest point
     if( colinear )
     {
-        auto less = []( const wxPoint& lhs, const wxPoint& rhs ) -> bool
-        {
-            if( lhs.x == rhs.x )
-                return lhs.y < rhs.y;
-            return lhs.x < rhs.x;
-        };
-
-        wxPoint top_left = std::min( { m_start, m_end, aLine->m_start, aLine->m_end }, less );
-        wxPoint bottom_right = std::max( { m_start, m_end, aLine->m_start, aLine->m_end }, less );
-
-        m_start = top_left;
-        m_end = bottom_right;
+        m_start = leftmost->m_start;
+        m_end = rightmost->m_end;
         return true;
     }
     return false;
-- 
2.11.0


Follow ups