Missing Points when drawing

I’m trying to run various snipits of code to draw things on Windows 10.
However I keep getting points missing (this isn’t isolated to the following code, it happens regularly).
Attached is just one example.
The points totally disappear if I don’t have noSmooth(); (but I want this as I only want black or white pixels
Any hints, or is this a Processing bug…

``````void setup() {
size(960,690);

noSmooth();
background(0);  // clear the screen in processing
stroke(255);    // set foreground colour to white
noLoop();
}

void draw() {
scale(0.1,-0.1);
translate(4800,-3450);

int steps=5;
int circleSteps=100;
float angStep=TWO_PI/circleSteps;

for (int i=0; i<steps; i++) {
for (int t=0; t<100; t++) {
float x1=(i*stepSize+t*(stepSize/100))*cos(t*angStep);
float y1=(i*stepSize+t*(stepSize/100))* sin(t*angStep);
//float x1=1500*cos(t*angStep);
//float y1=1500*sin(t*angStep);
point(x1,y1);
}
}
}
``````

1 Like

Hi dgm3333,

It would be nice to have the full code to be able to help you.

Sorry you were too quick, I accidentally submitted it before I’d finished.

It isn’t actually missing out any points–it is doing exactly what it being told to do. The thing is, the steps are larger than one pixel so there are gaps between the dots.

One solution to this is to draw a line than connects the current point to the previous point:

-Have 2 additional variables for the previous x and y positions (maybe `x0` and `y0`).
-Each iteration (where you have put the point function), draw a line. `line(x0, y0, x1, y1)`
-`x0` becomes what `x1` is now and `y0` becomes what the current `y1` is.

Click for solution
``````
float x0 = 0;
float y0 = 0;
int steps = 5;
int circleSteps = 100;
float angStep = Math.PI*2/circleSteps;

void setup() {
size(960,690);

noSmooth();
background(0);  // clear the screen in processing
stroke(255);    // set foreground colour to white
noLoop();
strokeWeight(2); //Sets the thickness of the strokes
}

void draw() {
scale(0.1,-0.1);
translate(4800,-3450);

float x1;
float y1;
for (int i=0; i<steps; i++) {
for (int t=0; t<100; t++) {
x1=(i*stepSize+t*(stepSize/100))*cos(t*angStep);
y1=(i*stepSize+t*(stepSize/100))* sin(t*angStep);
//x1=1500*cos(t*angStep);
//y1=1500*sin(t*angStep);
line(x0, y0, x1,y1);
x0 = x1;
y0 = y1;
}
}
}
``````

Use the `ellipse()` function instead of `point()`. Since you are scaling down a lot some points may disappear. It should fixed the issue with using ellipse and a radius of 10 for example.

Or you can also change your spiral parameters so you don’t need to scale it down so you directly get the right coordinates to draw your points.

Thanks for amazingly quick advice. However I’ve realised the solution is to parse to an int before passing values to the drawing function. The issue seems to be a result of passing a float to point() which causes it to drop some pixels (unfortunately that fix doesn’t work for ellipse()).

Replacing the above code with the following it works perfectly, so looks like it a glitch in the Processing drawing functions.

``````point((int)x1,(int)y1);
``````

@TheWizardBear - I wanted a single pixel at exactly the point I determine it, as per the original image the original formula resulted in 3 missing pixels (I wasn’t trying to join the pixels up).
@jb4x, ellipse glitch was far worse - that not only resulted in missing “pixels” (a lot more than the original point version), but the pixels look really messy as they aren’t actually one pixel either (eg the following image using ellipse size of 5). If I use the ellipse strategy but turn smooth back on the missing pixels return, but they vary significantly in intensity.

1 Like

Oh Ok. Glad you found a fix anyway.

Oh Drat, that wasn’t it - it worked with that example, but not others.
I think I will have remove the window scaling, and scale it just before converting to an int and passing to point

I don’t know how you made it works with changing `point(x1, y1)` to `point(int(x1), int(y1))`. The scaling down is still an issue - of course I tried before posting.

Now the ellipse fix is definitely not the best -as the result is quite crappy- but it does work. As I said in the previous post, use a size of 10 (not 5). Since you are scaling it down by a factor of 10 you want the end result to be at least 1 pixel wide to be sure to have it on screen.

The best option still is to get your position right relative to the size of your screen so you can draw real size shapes without scaling it down.

I think you are right, I was trying to avoid doing that as it requires reworking my original code snippets.
I won’t use scaling for anything but mirroring in the future.

You can use it for other purposes but with extreme value the result might not be the one expected.

Also it is known to have issues when using `stroke()`

``````void setup() {
size(960, 690);

noSmooth();
background(0);  // clear the screen in processing
stroke(255);    // set foreground colour to white
noLoop();
}

void draw() {
scale(0.1, -0.1);
translate(4800, -3450);

int steps=5;
int circleSteps=100;
float angStep=TWO_PI/circleSteps;
stroke(0, 200, 200);                              //KLL
strokeWeight(50);                                 //KLL
beginShape();                                     //KLL
for (int i=0; i<steps; i++) {
for (int t=0; t<100; t++) {
float x1=(i*stepSize+t*(stepSize/100))*cos(t*angStep);
float y1=(i*stepSize+t*(stepSize/100))* sin(t*angStep);
//float x1=1500*cos(t*angStep);
//float y1=1500*sin(t*angStep);
//point(x1,y1);                               //KLL
curveVertex(x1, y1);                          //KLL
}
}
endShape();                                       //KLL
}

``````

curveVertex joins up the pixels, so not what I am after.
However tested your idea and tried `beginShape(POINTS);` and `vertex(x1, y1);` but it actually drops more pixels than just using point(), so it still comes back to an issue with scaling.

``````void setup() {
size(960, 690);
background(0, 0, 90);  // clear the screen in processing
stroke(200, 200, 0);    // set foreground colour
noLoop();
}

void draw() {
translate(width/2, height/2);
int circleSteps=100, loops=3;
float angStep=TWO_PI/circleSteps;
for (int t=0; t<loops*circleSteps; t++) {
float r = circleSteps+t;
float x1=r * cos(t*angStep);
float y1=r * sin(t*angStep);
ellipse(x1, y1, 5, 5); //point(x1,y1);
}
}

``````

The general problem is that, if you are using scale, a point isn’t a pixel anymore – there is antialiasing / interpolation built in, always. When scaled down, hard decisions need to be made about which pixels display and which don’t (noSmooth) or how they compromise (smooth).

It would be far better to draw your points outside your scaling. So, don’t do this:

``````scale(0.1,-0.1);
point(x, y);
``````

``````point(x*0.1, y*-0.1);
``````

If you must scale everything else, even if you must draw at scale both before and after your points, you can still pop out of your transformation, draw points at 1-1, then re-enter your transformation.

``````pushMatrix();
scale(0.1,-0.1);
// draw some scaled things
popMatrix();
// draw unscaled points at scale-corresponding positions
point(x*0.1, y*-0.1);
pushMatrix();
scale(0.1,-0.1);
// draw some more scaled things
popMatrix();
``````

Anything else (stroke width, ellipses, spheres, etc) is a really hacky workaround that still sends your point through a scaling pipeline. If you want to draw a pixel, just do it at 1:1.

3 Likes