The center of a rect() stroke


#1

Hi.
Amplifying the image drawn with the code below, you will see a rectangle drawn with two ‘one-pixel-lines’ more, on the left and upper side of the rectangle, shown with the white lines, but just one-pixel-line on the right and lower side.
When I use an not even strokeWeight like 5, it will draw three more pixels on the left side out of the rectangle and one pixel within, and on the right side I see drawn three inner pixels and one outside the rectangle.The upper and down side have exactly two pixel on inner and outside.
Shouldn’t the rect() function be designed so that there is always the same number of pixels drawn outside and inside the rectangle on all sides? At the moment I have to do this manually to work in the exact boundary. Mutch more work!

void setup() {
  size(200, 200, P2D);
  strokeWeight(4);
  rect(50, 50, 50, 50);
  strokeWeight(1);
  stroke(255);
  line(50, 0, 50, 200);
  line(100, 0, 100, 200);
  line(0, 50, 200, 50);
  line(0, 100, 200, 100);
}

#2

I believe this is renderer specific. What you’re seeing is a result of how Java2D implements stroke and fill.

For example change the P2D to P3D to see a different behavior.

It’s debatable whether the rect() function should have been designed a certain way. But my guess is you’re probably going to have to stick with your custom implementation. Maybe make your life a little easier by extracting the behavior into a class or function so you only have to do it once?


#3

I see no difference between none, P2D, or P3D.
Coding has to be logic I think, and I do not see this in this function.


#4

P2D:

P2D

P3D:

P3D


#5

P3D seems to be right. On my device in Android mode it isn’t! Could you try this in Android mode? I don’t have a PC near right now.


#6

I don’t have a phone setup to do that, but I think it’s a bit moot. The point is that I believe this depends on your device and your renderer. It’s not Processing specifically doing anything. It’s up to the underlying renderer.

Processing could spend time and energy on making sure the stroke is the exact same on all renderers and devices, but in the grand scheme of things there are probably higher priority things for the (very small) team to focus on.

The nice thing is that Processing is open source, so if you think this is worth fixing, you can do that!


#7

If I had the capability I would try this, but unfortunately I just started to learn some Java. But as you are saying it also depends on the device, then it is worst then I tought it was. Even if I write my own Class I have to find out wich type of devices will react differently.


#8

I have fiddled around with the hint() function, and there
parameter
ENABLE_OPTIMIZED_STROKE
ENABLE_STROKE_PERRSPECTIVE
ENABLE_STROKE_PURE
But I also do not see any differences


#9

An even simpler way of understanding this is to look at this simple default behavior of rect() in JAVA2D with a one-line sketch:

rect(0, 0, width-1, height-1);

Notice how the way JAVA2D works relates to the frame of the sketch, and how it changes when strokeWeight changes. For example, with a different definition of the stroke location, a full-canvas rect would have an invisible stroke (it would appear outside the frame) – or it would have a hairline stroke, but changing the strokeWeight would have no effect (it would grow out, never in).


#10

Hmm. Actually, this P3D stroke join behavior looks like a bug…?

void setup() {
  size(200, 200, P3D);
  strokeWeight(20);
  rect(50, 50, 50, 50);
}

#11

@jeremydouglass
When you compare this with a 1 round border

void setup() {
size(150, 200, P3D);
strokeWeight(20);
rect(50, 30, 50, 50);
rect(50, 120, 50, 50, 1);
}

you get this on my device:

Coming back to the first code; my fear is that it is also, like @Kevin said, device related.
I need to ‘highlight’ cells in a grid with a 3 Weight stroke exactly within the cell without overdrawing the 1 Weight gridcell.
I really would like see others testing this.
Kevin’s code does not give a ‘correct’ dividing on my device.


#12

Here is what I see on Processing 3.3.6 (macOS 10.12.6):

void setup() {
  size(200, 200, P3D);
  strokeWeight(20);
  rect(50, 50, 50, 50);
}

That lower right corner looks like a bug. I’ll update to 3.3.7 first, then report it if it isn’t already in issues.

EDIT: I updated to 3.3.7, and there is no missing corner issue – everything looks good.


#13

@jeremydouglass
I tried you code on my Windows 10 desktop now, instead of on my android tablet, and something weird happened, The rectangle is gray and flickering when using P2D or P3D.!! However I don not see that notch of your image but the same shape of my last image. The default mode works normal.
I tested the first code also on my desktop in java mode and now it divides correctly,.
PS Using P 3.3.7


#14

The flickering can be stop by either calling noLoop() in setup or explicitly calling draw(). It is enough to have an empty body.

Related to the rect in P3D and Java mode, I get the same as what you reported. I am running on Win10 OS and P3.3.7. For Java2D I have a square with well defined corners. In P3D, I get all four corners trimmed. I do not observe the bug reported by jeremy.

Kf