0

I'm trying to draw a series of lines and shapes that connect to each-other. Because of some calculations that I'm doing the coordinates for the lines/shapes end up being non-integer numbers and in this case there's a gap between lines that end and start at the same non-integer coordinate.
For example for this code:

  void setup() {
    noLoop();
    size(500, 500);
  }
  
  void draw() {
  stroke(1);
  strokeWeight(100);
  strokeCap(SQUARE);
  line(0, 0, 0, 200.5);
  line(0, 200.5, 0, 401);
  }

I get this result (note the gap between the two lines): two lines next to each-other Tried this also in p5.js with the same result. How is this working? Should I just always round to integers after doing my math?

Nick Dima
  • 1,587
  • 2
  • 18
  • 36
  • I think you're seeing the strokeCap(). Try moving strokeCap() down one line. – apodidae Jan 10 '22 at 22:24
  • Having the strokeCap(SQUARE) before drawing anything should apply it to all the lines after that. In my example both lines have the square cap. I was mostly interested in what's the logic behind this behaviour with non-integer coordinates. If you just change 200.5 to 200 the gap is gone. – Nick Dima Jan 10 '22 at 23:32
  • Demo has been revised to include more options after adding background() to draw(). – apodidae Jan 11 '22 at 07:45

1 Answers1

0

After adding a background() call to the draw() the problem now appears to be with the SQUARE strokeCap as I initially thought and not the noLoop(). REM out strokeCap(SQUARE) and it runs ok. UN-REM it and the lines come back with or without noLoop(); PROJECT caps and no caps are still without lines, with or without noLoop(). I don't think the float values make a difference. Note that I removed the decimal values for strokeCap(SQUARE) to rule this out as a possibility. I'm unable to tell you why the lines occur with strokeCap(SQUARE), but the only way that I see to get rid of the lines is to use the PROJECT option, no caps at all, or keep them, but overlap the ends by 1 point. For whatever it's worth, Processing Reference states that all parameters for line() are floats.

void setup() {
  size(500, 500);
  noLoop();
}

void draw() {
  background(209); // Added and it makes a difference
  stroke(0);
  strokeWeight(50);
  // NO cap
  line(60, 80, 180.3, 80);  
  line(180.3, 80, 280.8, 80);
  line(280.8, 80, 380.5, 80);
  // (SQUARE) cap
  strokeCap(SQUARE); // REM this out to get rid of lines
  line(60, 160, 160, 160);
  line(160, 160, 260, 160);
  line(260, 160, 360, 160);
  // (PROJECT) cap
  strokeCap(PROJECT);
  line(60, 260, 160.5, 260);
  line(160.5, 260, 260.5, 260);
  line(260.5, 260, 360.5, 260);
  // (SQUARE) cap with 1 point of overlap
  strokeCap(SQUARE); // No lines with overlap
  line(60, 360, 160.8, 360);
  line(159.8, 360, 260.3, 360);
  line(259.3, 360, 360.5, 360);
}

apodidae
  • 1,988
  • 2
  • 5
  • 9
  • You're right, testing some more in Processing seems that the gap is present with integer values as well. I was working in p5.js and that's where I encountered the difference. Sorry, I should have tested better in Processing as well. Here's a p5.js sketch that demos this: https://editor.p5js.org/nickdima/sketches/CTXTyrNa6 – Nick Dima Jan 11 '22 at 21:41
  • And as a side note, in Processing, not calling strokeCap just uses the default value which is ROUNDED. – Nick Dima Jan 11 '22 at 21:42
  • This is getting even weirder. It seems that on my MacBook Pro's screen the same sketch has no gaps between the lines. While on my external screen, which is a lower res, the gap is present (only for the non-integers). Probably it has something to do with subpixel rendering in the browser. – Nick Dima Jan 11 '22 at 22:10
  • The MacBook Pro probably is a 'retina' which has twice the number of pixels if I recall correctly. I've also posted in the Processing Forum to see if we can get more information about the source code over there. I do know that an issue of using strokeCap(SQUARE) with a point has previously been raised, but to me that would almost be predictable given the small size of a point. – apodidae Jan 11 '22 at 22:42
  • I just ran the above demo in the p5.js web editor and I don't see any lines (even with my magnifying glasses on). So my new conclusion is that the problem is only seen with the desktop version. I use the same monitor (4k) for both the Processing IDE and the p5.js web editor. The renderers could be different: one uses macOS (java?) and the other uses a renderer from the web?? I would expect both to use openGL, but I think Mac quit supporting it; if so I'm not sure what it uses instead, unless Processing editor provides a copy. – apodidae Jan 12 '22 at 01:12
  • Yeah, I guess you don't see the gap because you're testing on a 4K monitor. My external monitor has lower res and that's where I see the gap. – Nick Dima Jan 12 '22 at 15:03
  • I do see the gap on my 4K monitor if I run the code in Processing editor but not if I run the code in p5.js web editor. That's why I'm suspicious of the renderers on the respective systems. There is a WEBGL for p5.js. Not sure what renderer Processing uses on a Mac. – apodidae Jan 12 '22 at 15:59
  • Found this thread on GitHub: https://github.com/processing/p5.js/issues/1516 The last comment talks about using a higher pixelDensity(), that seems to work. – Nick Dima Jan 12 '22 at 17:35
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/241012/discussion-between-apodidae-and-nick-dima). – apodidae Jan 12 '22 at 18:27