Redraw Line Bug?

I'm trying to draw a line, then redraw that same line using the background colour (I don't want to redraw the background) but something is being left behind.

I modified one of the examples on this page to test it:

https://p5js.org/reference/#/p5/blendMode

Here's my code. Am I doing something wrong or did I discover a bug?

background(0);
blendMode(REPLACE);
strokeWeight(30); // will work with a stroke weight of 1 as well - 30 is easier to see.
stroke(255);
line(25, 25, 75, 75);
stroke(0);
line(25, 25, 75, 75);

Answers

  • edited December 2016

    This is because the edges of the line aren't exact. There is a little bit of burring that happens to smooth out lines drawn at angles, to avoid them being sharp as pixels.

    This can be disabled using noSmooth():

    size(200,200);
    background(0);
    noSmooth();
    blendMode(REPLACE);
    strokeWeight(30);
    stroke(255);
    line(25, 25, 75, 75);
    stroke(0);
    line(25, 25, 75, 75);
    

    And the effect desired is achieved.

  • Thanks, but even with smoothing enabled, shouldn't the line be drawn the same way every time?

    I tried adding noSmooth() as you suggested. I still see the same problem.

  • edited December 2016

    There's also strokeCap() for line(): L-)
    http://p5js.org/reference/#/p5/strokeCap

  • edited December 2016

    In Processing Java, the excerpt below w/ just noSmooth() is enough for complete replacement: O:-)

    noSmooth();
    noLoop();
    
    background(0);
    strokeWeight(30);
    
    stroke(-1);
    line(25, 25, width - 25, height - 25);
    
    stroke(0);
    line(25, 25, width - 25, height - 25);
    

    However, if I paste that same code in Pjs, it suddenly fails. b-(
    Seems like noSmooth() is completely ignored there: :-q
    http://ProcessingJS.org/tools/processing-helper.html

    And the same goes to p5.js as well. noSmooth() doesn't seem to kick in at all.
    Even when applying both blendMode() + strokeCap() for workaround as well: ~X(

    noSmooth().blendMode(REPLACE);
    strokeCap(SQUARE).strokeWeight(30);
    background(0);
    
    stroke(255).line(25, 25, width - 25, height - 25);
    stroke(0).line(25, 25, width - 25, height - 25);
    
  • Thanks for the suggestion, but changing strokeCap() didn't fix the problem and I would ask the same question, shouldn't the line be drawn the same way both times in my example?

  • edited December 2016

    ... shouldn't the line be drawn the same way both times in my example?

    As implied many times in this forum thread already: "Not w/o noSmooth() active"! [-(

  • As implied many times in this forum thread already: "Not w/o noSmooth() active"!

    But why? Is there some random factor involved? Why should different pixels be used to draw the same line given the same configuration and same starting and ending points?

  • edited December 2016 Answer ✓

    Smoothness attempts to workaround existing pixels in order to avoid an ugly aliasing result. :-&

    But seems like, in latest browsers, smoothness can't be turned off.
    Or at least it's much harder to do so now. :|

  • edited December 2016

    Smoothness attempts to workaround existing pixels

    Ah, yes that explains it. That makes sense. I'll have to see if I can directly disable smoothing outside the p5 library.

  • From what I can tell by further research now that I know what I'm looking for, this isn't a p5 issue but a canvas issue with all the browsers. It seems there is no way to turn off anti-aliasing in the canvas even when using the canvas directly.

  • edited December 2016

    Something is off - AFAIK anti-aliasing should draw the exact same line every time as long as all other parameters (maybe even the driver version) remain constant.

  • Except that the first time, a white line is drawn against a black background. Then, during an attempt to erase that line, a black line is drawn over a white line on a black background. So, the conditions are different for the white and black lines, which matters if pixels are blended with whatever is beneath them.

    What I have found, is that if I redraw the black line enough times (10x works), it eventually erases all of the pixels from the original white line.

  • Oh, that way.
    Alpha channel does act a bit non-intuitive.

  • edited January 2017

    @batman42ca --

    Another way of approaching problems like this is to draw your temporary lines into a separate transparent image layer (e.g. PGraphics) for compositing. When you want the line to be un-drawn, clear or don't-render the separate image layer where you drew the line.

    This is a general approach -- it works with smooth lines, no-smooth lines, partially transparent lines, gradients, and all kinds of things where trying to calculate the "undo-draw" might be imprecise, difficult, or impossible.

  • That's an interesting approach. I'll have to give that a try and see what happens in my application. Thanks.

Sign In or Register to comment.