Breaking overlapping lines

Post questions on how to use or achieve an effect in Inkscape.
tginsandiego
Posts: 8
Joined: Sun May 11, 2014 8:14 am

Breaking overlapping lines

Postby tginsandiego » Fri Jun 12, 2015 2:27 am

Hey folks,


I have drawings with a lot of lines that don't quite match up. Imagine an X drawn with two lines and the desired result is similar to a carrot: ^ The simplest operation would be to break the lines at the point of intersection, then delete the unwanted segments.

The "Cut Path" operation breaks the lower path at points of intersection with the higher path, but deletes the higher path. So this is the way I've figured out how to achieve this effect:

1. Copy both lines
2. Select the lines
3. Path -> Cut path (which results in the top line going away)
4. Paste in Place (to get both original lines back)
5. Raise the lower pasted line to top (so that it becomes the cutter instead of the cuttee)
6. Select the (pasted) lines
7. Path -> cut path
8. Delete the unwanted broken-apart pieces from steps 3 and 7

a LOT of steps, just to introduce breaks at the point of intersection of two lines. Is there a faster/better way?

Many thanks!

Terry

User avatar
brynn
Posts: 10309
Joined: Wed Sep 26, 2007 4:34 pm
Location: western USA
Contact:

Re: Breaking overlapping lines

Postby brynn » Fri Jun 12, 2015 10:46 am

That seems as good a way as any. This is one of those things for which there are several ways to do it, with Inkscape. Here's how I usually break 2 paths at the point where they intersect.

Enable snapping with the Snap to Path Intersection option engaged. Drag a Guide line out (and depending if you have your preferences set up right*) the Guide will snap to the intersection. Then you can select 1 path with the Node tool, and double click to add a new node. Then you can drag that node to the intersection of the Guide and the other path (where it will snap). Then do the same for the other path. And then you can select both new nodes and click Break Path at Selected Nodes button (Node tool control bar).

* The right preference for the guide to snap -- Hhmm...I thought for a guide to snap while you are dragging it, there was an option to choose -- I thought in Document Properties (not exactly a "preference" so sorry for that wrong word). But I can't find that option anywhere. Maybe dragging a guide will snap by default now?

And the other thing I wanted to say. I'm not sure how you got into the position of needing to break the paths at their intersection. Possibly it's just your workflow. And possibly you need the other piece of the paths, after you break them at their intersection. But it might be possible with snapping (depending on what you're doing on the canvas) to have the lines already connected by their end nodes, and not have to break them (by whatever means).

For example. If you drag out the guide like I said, and snap it to the intersection of the paths, you can then drag the end node of each path, and it will snap to the intersection of the guide and the other path (which is the place where the paths originally intersected). Same result except you don't have extra pieces of paths leftover. Also, will only work if these are straight lines, or path segments. If there are any curves to be respected, this would not work.

I'm sure others will chime in with other ways to do this :D

User avatar
ianp5a
Posts: 106
Joined: Thu Sep 02, 2010 1:30 am

Re: Breaking overlapping lines

Postby ianp5a » Sat Jun 13, 2015 1:12 am

Dragging the guides would only work with straight segments. With curves another solution would be needed.
It would be good to have a "Keep/No keep" option as in some software.
If accuracy is not too important, adding a node at the intersection by eye might be quickest.

I find all of the path operations, by stacking order, counter intuitive. I'm often surprised, and have to undo and repeat. Until I get a satisfactory result. There should be preview, reverse order and keep options.

tginsandiego
Posts: 8
Joined: Sun May 11, 2014 8:14 am

Re: Breaking overlapping lines

Postby tginsandiego » Sun Jun 14, 2015 1:19 am

Perhaps an extension to "Add Nodes At Intersections" would be possible? Because once the nodes are in place, cutting the extraneous bits and combining the end points would be a lot fewer steps and mouse/key operations

tginsandiego
Posts: 8
Joined: Sun May 11, 2014 8:14 am

Re: Breaking overlapping lines

Postby tginsandiego » Sun Jun 14, 2015 2:38 am

Yikes! Looks like people have been proposing/requesting this functionality for years!

http://wiki.inkscape.org/wiki/index.php/Intersection_Tools
http://wiki.inkscape.org/wiki/index.php/SpecPathIntersectionCutter

Using the addnode python extension as a starting point, I thought I would take a stab at this. Could use some help from people who know python and cubicsuperpath and bemisc functions though! HELP! :-)


Code: Select all

#!/usr/bin/env python
'''

This MOD to addnodes.py is to add nodes at intersections of lines. 
Original file text is below

This extension either adds nodes to a path so that
    a) no segment is longer than a maximum value
    or
    b) so that each segment is divided into a given number of equal segments

Copyright (C) 2005,2007 Aaron Spike, aaron@ekips.org

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
'''

import inkex
import cubicsuperpath, simplestyle, copy, math, re, bezmisc

def numsegs(csp):
    return sum([len(p)-1 for p in csp])
   
def tpoint((x1,y1), (x2,y2), t = 0.5):
    return [x1+t*(x2-x1),y1+t*(y2-y1)]
   
def cspbezsplit(sp1, sp2, t = 0.5):
    m1=tpoint(sp1[1],sp1[2],t)
    m2=tpoint(sp1[2],sp2[0],t)
    m3=tpoint(sp2[0],sp2[1],t)
    m4=tpoint(m1,m2,t)
    m5=tpoint(m2,m3,t)
    m=tpoint(m4,m5,t)
    return [[sp1[0][:],sp1[1][:],m1], [m4,m,m5], [m3,sp2[1][:],sp2[2][:]]]
   
def cspbezsplitatlength(sp1, sp2, l = 0.5, tolerance = 0.001):
    bez = (sp1[1][:],sp1[2][:],sp2[0][:],sp2[1][:])
    t = bezmisc.beziertatlength(bez, l, tolerance)
    return cspbezsplit(sp1, sp2, t)
   
def cspseglength(sp1,sp2, tolerance = 0.001):
    bez = (sp1[1][:],sp1[2][:],sp2[0][:],sp2[1][:])
    return bezmisc.bezierlength(bez, tolerance) 
     
def csplength(csp):
    total = 0
    lengths = []
    for sp in csp:
        lengths.append([])
        for i in xrange(1,len(sp)):
            l = cspseglength(sp[i-1],sp[i])
            lengths[-1].append(l)
            total += l           
    return lengths, total
   
def numlengths(csplen):
    retval = 0
    for sp in csplen:
        for l in sp:
            if l > 0:
                retval += 1
    return retval

class SplitIt(inkex.Effect):
    def __init__(self):
        inkex.Effect.__init__(self)
        self.OptionParser.add_option("--segments",
                        action="store", type="int",
                        dest="segments", default=2,
                        help="Number of segments to divide the path into")
        self.OptionParser.add_option("--max",
                        action="store", type="float",
                        dest="max", default=2,
                        help="Number of segments to divide the path into")
        self.OptionParser.add_option("--method",
                        action="store", type="string",
                        dest="method", default='',
                        help="The kind of division to perform")

    def effect(self):

        for id1, node1 in self.selected.iteritems():
            if node1.tag == inkex.addNS('path','svg'):
                p1 = cubicsuperpath.parsePath(node1.get('d'))
               
                for id2, node2 in self.selected.iteritems():
                    p2 = cubicsuperpath.parsePath(node2.get('d'))
               
                    #lens, total = csplength(p)
                    #avg = total/numlengths(lens)
                    #inkex.debug("average segment length: %s" % avg)
   
                    new1 = []
                    for sub1 in p1:
                   
                    ''''
                    Original code for splitting lines is below. 
                    Instead we want to determine if P1 intersects P2 and if so, add node to P1 at intersection.
                    Sample code for determining cubic interesects is mentioned here:
                       https://www.particleincell.com/2013/cubic-line-intersection/
                       https://sites.google.com/site/nurbsintersection/home/demo-code                       
                    ''''
                   
                    ''''
                        new1.append([sub1[0][:]])
                        i1 = 1
                        while i1 <= len(sub1)-1:
                            length1 = cspseglength(new1[-1][-1], sub1[i])
                           
                            if self.options.method == 'bynum':
                                splits1 = self.options.segments
                            else:
                                splits1 = math.ceil(length/self.options.max)
   
                            for s1 in xrange(int(splits),1,-1):
                                new1[-1][-1], next, sub1[i] = cspbezsplitatlength(new1[-1][-1], sub1[i], 1.0/s)
                                new1[-1].append(next[:])
                            new1[-1].append(sub[i])
                            i1+=1

                       
                    node1.set('d',cubicsuperpath.formatPath(new))
                    ''''

if __name__ == '__main__':
    e = SplitIt()
    e.affect()


# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 encoding=utf-8 textwidth=99

User avatar
brynn
Posts: 10309
Joined: Wed Sep 26, 2007 4:34 pm
Location: western USA
Contact:

Re: Breaking overlapping lines

Postby brynn » Sun Jun 14, 2015 8:43 am

tginsandiego wrote:Yikes! Looks like people have been proposing/requesting this functionality for years!

http://wiki.inkscape.org/wiki/index.php/Intersection_Tools
http://wiki.inkscape.org/wiki/index.php/SpecPathIntersectionCutter

You might also want to check out the bug tracker (Launchpad) where there may be new feature requests about this ("wishlist" bug reports) and other discussion. I expect you'll find multiple requests (including for a razor or knife tool, true cropping tool, and a few other ideas). I'm pretty sure there's a recent one about adding a new node at path intersections, if that's what you're thinking.
Using the addnode python extension as a starting point, I thought I would take a stab at this. Could use some help from people who know python and cubicsuperpath and bemisc functions though! HELP! :-)

Oh wow, that's awesome!! Thanks for your contribution to this :D

Since this is primarily a user forum, there may not be anyone who can help you with the code here.....or at least they might not come along anytime soon. But you'll probably get lots of help from the development mailing list. Or if you don't want all that mail, the user list is less busy, and developers and others who can help with the code will see your message there, as well. Info on joining the lists: https://inkscape.org/en/community/mailing-lists/.

And for info on all kind of development topics: https://inkscape.org/en/develop/ and https://inkscape.org/en/develop/getting-started/. I've made a request for a guide to writing Inkscape extensions (yes another wishlist item), but for now, here's what we have to help people learn how to write extensions: https://inkscape.org/en/develop/#extns (Although I do sincerely hope someone will write a guide some day soon!)

Uummm....there also are a couple of IRC channels where you might get help. Since I don't use those much, I don't know if it's possible to get help with code.....but I guess so, in some cases. The IRC channel for users (where developers also help) https://inkscape.org/en/community/discussion/, and further down that page you'll find a link for the other channel.


Return to “Help with using Inkscape”