Overlapping paths



  • schrofer_stroke_o_heartline.png

    A quick and hopefully not-too-dumb question about BezierPath() overlaps: what's the Boolean operation would allow me to get rid of an overlap like the one in the upper-left-hand corner of this path? removeOverlap() erases the whole path …

    (Gustavo, if you're reading this, I stole the diagram scheme and colors from you.)



  • hello @MauriceMeilleur,

    I’ve created a simplified version of your shape for testing (see below). remove overlap works as expected, the inner shape is preserved:

    removeOverlapTest.gif

    B = BezierPath()
    B.moveTo((10, 90))
    B.lineTo((90, 90))
    B.lineTo((90, 10))
    B.lineTo((10, 10))
    B.lineTo((10, 90))
    B.lineTo((40, 90))
    B.lineTo((40, 40))
    B.lineTo((60, 40))
    B.lineTo((60, 60))
    B.lineTo((10, 60))
    B.closePath()
    
    newPage(100, 100)
    frameDuration(3)
    fill(None)
    stroke(1, 0, 0)
    drawPath(B)
    
    B.removeOverlap()
    
    newPage(100, 100)
    frameDuration(3)
    fill(None)
    stroke(1, 0, 0)
    drawPath(B)
    
    # saveImage('removeOverlapTest.gif')
    

    it would help if you could post your actual bezier points, so we can see if it’s a problem in the data.

    ps. the color scheme is a nice reminder to add an illustration to the arcTo docs 🙂



  • Gustavo, thanks. Here's the path.points from the outline above. Sorry I haven't had a chance yet to get round() inserted into all the calculations where it needs to be, yet.

    [(-125.0, 275.0),
    (-125.0, -100.0),
    (-125.0, -99.99999999999999),
    (-125.0, -113.80711874576983),
    (-113.80711874576983, -124.99999999999999),
    (-100.0, -124.99999999999999),
    (125.0, -125.0),
    (125.0, 100.0),
    (125.0, 100.0),
    (125.0, 113.80711874576983),
    (113.80711874576983, 125.0),
    (100.0, 125.0),
    (-275.0, 125.0),
    (-275.0, 275.0),
    (100.0, 275.0),
    (99.99999999999999, 275.0),
    (196.64983122038882, 275.0),
    (275.0, 196.64983122038882),
    (275.0, 100.0),
    (275.0, -275.0),
    (-100.0, -275.0),
    (-100.00000000000003, -275.0),
    (-196.64983122038888, -275.0),
    (-275.0, -196.64983122038882),
    (-275.0, -99.99999999999997),
    (-275.0, 275.0),
    (-125.0, 275.0)]



  • By the way, here's the context. The appearance of the black-filled outline is correct, but I want to lose the overlap to allow me to layer and selectively remove copies of the outlines to create Schrofer's various stroke effects.

    schrofer_stroke_m_heartline.png



  • @MauriceMeilleur thanks for the points. remove overlap also works as expected with a lineTo-only version of the shape:

    pts = [(-125.0, 275.0), (-125.0, -100.0), (-125.0, -99.99999999999999), (-125.0, -113.80711874576983), (-113.80711874576983, -124.99999999999999), (-100.0, -124.99999999999999), (125.0, -125.0), (125.0, 100.0), (125.0, 100.0), (125.0, 113.80711874576983), (113.80711874576983, 125.0), (100.0, 125.0), (-275.0, 125.0), (-275.0, 275.0), (100.0, 275.0), (99.99999999999999, 275.0), (196.64983122038882, 275.0), (275.0, 196.64983122038882), (275.0, 100.0), (275.0, -275.0), (-100.0, -275.0), (-100.00000000000003, -275.0), (-196.64983122038888, -275.0), (-275.0, -196.64983122038882), (-275.0, -99.99999999999997), (-275.0, 275.0), (-125.0, 275.0)]
    
    B = BezierPath()
    for i, pt in enumerate(pts):
        if i == 0:
            B.moveTo(pt)
        else:
            B.lineTo(pt)
    B.closePath()
    
    # (un)comment this line to test
    # B.removeOverlap()
    
    newPage(800, 800)
    translate(400, 400)
    fill(None)
    stroke(1, 0, 0)
    strokeWidth(8)
    drawPath(B)
    

    I don’t think the lack of curveTos plays a role in the result (but you never know).

    let’s try it the other way around: can you provide a simple example in code of a shape where the whole path is erased when removing overlap? thanks!



  • @gferreira As soon as I get a chance first thing in the AM. By the way and in case it matters (though I don't see why it should), the curves are drawn with arcTo().



  • Okay, now I feel embarrassed: just tried a test, as follows:

    canvas = 500
    
    newPage(canvas, canvas)
    translate(canvas/2, canvas/2)
    path = BezierPath()
    path.arc((0, 0), 200, 0, 540, False)
    path.lineTo((-100, 0))
    path.arc((0, 0), 100, 540, 0, True)
    path.closePath()
    stroke(0)
    fill(None)
    path.closePath()
    
    path.removeOverlap()
    drawPath(path)
    
    saveImage('~/Desktop/overlap_test.png')
    

    and got this:

    overlap_test.png

    Just what I thought should happen! So I tried again with the original code I'm working on—and I swear I put the removeOverlap() call in the same place—and here's the result:

    schrofer_stroke_m_heartline.png

    So, great! The function works as I originally thought it should! But, on the other hand, I have no idea why it wouldn't perform when I first tried it.


  • admin

    A wild guess: if you have twice the same outline on top of each other, it is possible a remove overlap can freak out

    Wild guess 2: you had some open paths, which are removed by a remove overlap



  • I can't say for sure, but just thinking about the editing I'd been doing when I ran into the problem, open paths would be the more likely explanation. Anyway, it's working now—time to move on to new problems. 🙂