The code below renders rectangular checkboxes: Dots centered in frames. I think the code should produce a symmetrical result (prefectly centered dot; equal distance between frame and dot on all sides) but it doesn’t:
This happens under Windows with Processing 3/Java 8 (it seems ok on my Android device, which has higher pixel density). Is this my mistake or an issue of Processing?
// distance between frame and dot (on all sides of dot), here 1/5 of font height
int dot_spacing = Font_H / 5;
// calculate position and width of dot (height == width)
int dot_x = X_Checkbox + dot_spacing;
int dot_w = H_Checkbox - dot_spacing - dot_spacing;
// checkbox frame
stroke(...);
noFill();
rect (X_Checkbox, y, H_Checkbox, H_Checkbox);
// checkbox dot
noStroke();
fill (Palette_ARGB[Palette][Legend_PenFG]);
rect (dot_x, y + dot_spacing, dot_w, dot_w);
Numbers would help a bit, but i’ll just make them up.
Lets say the fontH is 10, x_Checkbox = 10, H_Checkbox = 10 and y = 10:
dot_x = 10 + 2 = 12;
dot_w = 10 - 2 - 2 = 6;
then :
rect(10, 10, 10, 10);
rect(12, 12, 6, 6);
which results in the dot being 2 dist from the left and top, but 4 from right and bottom.
Just remove one from the 2 - dot_spacings s and it should be fine.
Please provide a runnable sketch.
It is impossible for us to know why your checkmarks and checkboxes are not lining up when we don’t know the value of a single variable.
But if you use rectMode(CENTER), they should be lining up perfectly.
rect(10, 10, 10, 10) … rect(12, 12, 6, 6) … which results in the dot being 2 dist from the left and top, but 4 from right and bottom
I don’t get the explanation. The values seem correct to me. The frame is 10x10 and the dot is 6x6. That means there should be 2 pixels on all sides of the dot (including the outer frame), hence 2 pixel offset to coordinates of outer frame (10 + 2)?!
if you use rectMode(CENTER),
I use the default mode, CORNER (there is more stuff in my app to render near those boxes).
Please provide a runnable sketch
Okay…
void setup() { }
void
draw()
{
int dot_spacing = 2; // distance between frame and dot (on all sides of dot)
int X_Checkbox = 10;
int Y_Checkbox = 10;
int H_Checkbox = 10; // width = height
// calculate position and width of dot (height == width)
int dot_x = X_Checkbox + dot_spacing;
int dot_w = H_Checkbox - dot_spacing - dot_spacing;
// checkbox frame
stroke(0);
noFill();
rect (X_Checkbox, Y_Checkbox, H_Checkbox, H_Checkbox);
// checkbox dot
noStroke();
fill (0);
rect (dot_x, Y_Checkbox + dot_spacing, dot_w, dot_w);
}
Well, to solve your problem, just add +1 to dot_w.
The code is right and it executes right. The problem lies in how the pixels are displayed from left to right.
Or if you need stroke you’ll have to add the stroke size to dot_x. Note that stroke(0) still is one pixel in size. So you’ll have to add strokeWeight + 1 to dot_x to get the right size.
will work correctly if you comment out the noStroke(); line.
This centers the dot. Unfortunately the dot gets a weird 3D effect if noStroke() is omitted (and if rendering with alpha is used). Enlarged example:
void setup() {}
void
draw()
{
int dot_spacing = 3; // distance between frame and dot (on all sides of dot)
int X_Checkbox = 10;
int Y_Checkbox = 16;
int H_Checkbox = 16; // width = height
background(255);
// calculate position and width of dot (height == width)
int dot_x = X_Checkbox + dot_spacing;
int dot_w = H_Checkbox - dot_spacing - dot_spacing;
strokeWeight(1.1);
// checkbox frame
stroke(0, 64);
noFill();
rect (X_Checkbox, Y_Checkbox, H_Checkbox, H_Checkbox);
// render dot
stroke(0, 64);
fill (0, 64);
rect (dot_x, Y_Checkbox + dot_spacing, dot_w, dot_w);
}
I thought I could fix this with a fully transparent stroke for the dot’s rect but then the dot is off-center again.
you’ll have to add the stroke size to
If I fiddle with the coordinates and widths until it’s right under Windows, it’s wrong under Android. Under Android, my original code leads to a perfect result. I guess I’ll have to use platform-specific kludges.
I guess I am more concerned that it operates differently under Android versus Windows, even though both are Java. I wonder then about p5js and python as well. This is undoubtedly due to differences in the underlying graphics packages the implementations use. I would recommend filing a bug report.
If a grey rectangle is rendered on a white background, some edges stay sharp but some get smoothed - they do not get rendered equally (as one would expect?):
With this kind of asymmetry in the filled rect() (but not in the frame), it seems impossible to achieve pixel-perfect alignment. I’ll try to use an image for the checkbox and scale it to the desired size.