trying to make overlapping rectangles on canvas grid - random

I´m trying to make a grid with overlapping squares that change between black and white. So far I could do the grid responsive to the canvas, also assign a random color, but the overlapping part doesnt quite work out. I tried adding a black stroke to the black squares but somehow there are very small squares appearing. Any ideas? Here´s my code:
void setup() {
size(900, 900);
}
void draw() {
fill(255);
noStroke();
int divW=width/6;
int horS=divW/5*2;
int divH=height/6;
int verS=divH/5*2;
for (int p = 0; p < width; p = p+divH-verS) {
for (int q = 0; q < height; q = q+divW-verS) {
push();
int col = int(random(100));
if (col <= 65) {
fill(0);
}
rect(q, p, divW, divH);
pop();
}
}
if (frameCount == 10) {
exit();
}
saveFrame("output/2grid65_o###.png");
}
IMG of what I was getting without the stroke
IMG of what I´m getting with the stroke
IMG of what I want (see the overlap between squares?)

It looks like the white squares are overlapping the strokes on the black squares, which gives you those little bits sticking out from behind.
Since your background is white, a simple solution would be to not draw the white squares (just let the background show through). Then you should be able to use your stroke method to have them overlap.
int col = int(random(100));
if (col <= 65) {
// only draw the square if it's black
fill(0);
rect(q, p, divW, divH);
}

Related

How to control how many times something is shown in Processing?

void setup() {
background(0);
fullScreen();
}
void draw() {
int g = 0;
float cCount = map(mouseY, 0, height, 1, 20);
for (int i = 0; i < width; i+=50) {
while(g < cCount) {
circle(i, mouseY, 20);
}
}
}
So what I'm trying to do is change the number of times circles are shown on the screen as I move the mouse. When the mouse moves down, more circles are shown on the screen all with the same Y coordinate but the distance between each circle is 50. As I move the mouse up, less circles are shown. Max circles is 20 and min is 1. I don't know how to set up a way for the number of circles to change as I move the mouse?
I think your approach is correct, but your code has some bugs that are not related to the problem itself.
In your while (g < cCount) loop, neither g nor cCount is updated, resulting in an infinite loop, but you don't really need that while loop anyway.
The following should work (but I haven't checked running the code myself, so it might have some bugs.
void draw() {
int circleCount = round(map(mouseY, 0, height, 1, 20));
for (int i = 0; i < circleCount; i+=1) {
circle(i*50, mouseY, 20);
}
}

Using Processing for image visualization: pixel color thresholds

Image to be manipulated, hoping to identify each white dot on each picture with a counter
PImage blk;
void setup() {
size(640, 480);
blk=loadImage("img.png");
}
void draw () {
loadPixels();
blk.loadPixels();
int i = 0;
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int loc = x+y*width;
pixels [loc] = blk.pixels[loc];
if (blk.pixels[loc] == 0) {
if (blk.pixels [loc]+1 != 0) {
i++;
}
}
float r = red(blk.pixels[loc]);
float g = green(blk.pixels[loc]);
float b = blue(blk.pixels[loc]);
pixels [loc] = color(r, g, b);
}
}
System.out.println (i);
updatePixels();
}
The main problem is within my if statement, not sure to approach it logically.
I'm unsure where this is exactly going, but I can help you find the white pixels. Here, I just counted 7457 "white" pixels (then I turned them red so you can see where they are and adjust the threshold if you want to get more or less of them):
Of course, this is just a proof of concept which you should be able to adapt to your needs.
PImage blk;
void setup() {
size(640, 480);
blk=loadImage("img.png");
blk.loadPixels();
int whitePixelsCount = 0;
// I'm doing this in the 'setup()' method because I don't need to do it 60 times per second
// Once it's done once I can just use the image as modified unless you want several
// different versions (which you can calculate once anyway then store in different PImages)
for (int i = 0; i < blk.width * blk.height; i++) {
float r = red(blk.pixels[i]);
float g = green(blk.pixels[i]);
float b = blue(blk.pixels[i]);
// In RGB, the brightness of each color is represented by it's intensity
// So here I'm checking the "average intensity" of the color to see how bright it is
// And I compare it to 100 since 255 is the max and I wanted this simple, but you can
// play with this threshold as much as you like
if ((r+g+b)/3 > 100) {
whitePixelsCount++;
// Here I'm making those pixels red so you can see where they are.
// It's easier to adjust the threshold if you can see what you're doing
blk.pixels[i] = color(255, 0, 0);
}
}
println(whitePixelsCount);
updatePixels();
}
void draw () {
image(blk, 0, 0);
}
In short (you'll read this in the comments too), we count the pixels according to a threshold we can adjust. To make things more obvious for you, I colored the "white" pixels red. You can lower or raise the threshold according to what you see this way, and once you know what you want you can get rid of the color.
There is a difficulty here, which is that the image isn't "black and white", but more greyscale - which is totally normal, but makes things harder for what you seem to be trying to do. You'll probably have to tinker a lot to get to the exact ratio which interests you. It could help a lot if you edited the original image in GiMP or another image software which lets you adjust contrast and brightness. It's kinda cheating, but it it doesn't work right off the bat this strategy could save you some work.
Have fun!

How do I change the color from white to black step by step of a rectangle, when I move my mouse away?

I have a question. How do I change the color of a rectangle from white to black step by step, when I move my mouse away? I'm kinda new to this.
I've tried a bit:
void setup () {
size (200,200);
}
void draw () {
background (0);
stroke (255);
line (100,0,100,200);
line (0,100,200,100);
// Fill a black color
noStroke ();
fill (255);
// Depending on the mouse location, a different rectangle is displayed.
if (mouseX < 100 && mouseY < 100) {
rect (0,0,100,100);
} else if (mouseX > 100 && mouseY < 100) {
rect (100,0,100,100);
} else if (mouseX < 100 && mouseY > 100) {
rect (0,100,100,100);
} else if (mouseX > 100 && mouseY > 100) {
rect (100,100,100,100);
}
}
I would appreciate that, if anyone could help me.
Thanks.
The call fill(255); is setting the rectangle color to white. Use fill(0); to set the rectangle to black, or fill(x); for any value x between 0 and 255 for shades of grey.
To make a fade, you'll need to draw multiple rectangles (drawing all of them is easiest) on each draw() call. The current box will be in white, where the mouse is. Others will be fading to black. So you'll need variables for each box indicating its current color.
Here's my version:
int boxColor1;
int boxColor2;
int boxColor3;
int boxColor4;
void setup () {
size (200,200);
boxColor1 = boxColor2 = boxColor3 = boxColor4 = 0;
}
void draw () {
background (0);
// Fill a black color
noStroke ();
// Subtrack 10 from each box color, but don't go below zero
boxColor1 = max( 0, boxColor1-10 );
boxColor2 = max( 0, boxColor2-10 );
boxColor3 = max( 0, boxColor3-10 );
boxColor4 = max( 0, boxColor4-10 );
// Depending on the mouse location, a different rectangle is displayed.
if (mouseX < 100 && mouseY < 100) {
boxColor1 = 255;
} else if (mouseX > 100 && mouseY < 100) {
boxColor2 = 255;
} else if (mouseX < 100 && mouseY > 100) {
boxColor3 = 255;
} else if (mouseX > 100 && mouseY > 100) {
boxColor4 = 255;
}
fill (boxColor1);
rect (0,0,100,100);
fill (boxColor2);
rect (100,0,100,100);
fill (boxColor3);
rect (0,100,100,100);
fill (boxColor4);
rect (100,100,100,100);
// Draw edge lines last, over the top
stroke (255);
line (100,0,100,200);
line (0,100,200,100);
}
If there are a lot of boxes, you should use an array, or some data structure instead of many different variables like boxColor1, boxColor2 etc.
If I understand your question, you want to show a grid of rectangles, and you want a rectangle to turn white and stay white when the mouse exits that rectangle. Is that right?
If so, then you need to keep track of whether each rectangle should be black or white. The simplest approach might be a 2D array of boolean values. Each cell in the array will represent a single square in your grid.
Set the corresponding cell in the array to true when you want that square to turn white. Then loop over the array and draw each square using the values in the array to determine the color.

Sierpinski carpet in processing

So I made the Sierpinski carpet fractal in processing using a Square data type which draw a square and has a function generate() that generates 9 equal squares out of itself and returns an ArrayList of (9-1)=8 squares removing the middle one (it is not added to the returned ArrayList) in order to generate the Sierpinski carpet.
Here is the class Square -
class Square {
PVector pos;
float r;
Square(float x, float y, float r) {
pos = new PVector(x, y);
this.r = r;
}
void display() {
noStroke();
fill(120,80,220);
rect(pos.x, pos.y, r, r);
}
ArrayList<Square> generate() {
ArrayList<Square> rects = new ArrayList<Square>();
float newR = r/3;
for (int i=0; i<3; i++) {
for (int j=0; j<3; j++) {
if (!(i==1 && j==1)) {
Square sq = new Square(pos.x+i*newR, pos.y+j*newR, newR);
rects.add(sq);
}
}
}
return rects;
}
}
This is the main sketch which moves forward the generation on mouse click -
ArrayList<Square> current;
void setup() {
size(600, 600);
current = new ArrayList<Square>();
current.add(new Square(0, 0, width));
}
void draw() {
background(255);
for (Square sq : current) {
sq.display();
}
}
void mousePressed() {
ArrayList<Square> next = new ArrayList<Square>();
for(Square sq: current) {
ArrayList<Square> rects = sq.generate();
next.addAll(rects);
}
current = next;
}
The problem :
The output that I am getting has very thin white lines which are not supposed to be there :
First generation -
Second generation -
Third generation -
My guess is that these lines are just the white background that shows up due to the calculations in generate() being off by a pixel or two. However I am not sure about how to get rid of these. Any help would be appreciated!
Here's a smaller example that demonstrates your problem:
size(1000, 100);
noStroke();
background(0);
float squareWidth = 9.9;
for(float squareX = 0; squareX < width; squareX += squareWidth){
rect(squareX, 0, squareWidth, height);
}
Notice that the black background is showing through the squares. Please try to post this kind of minimal example instead of your whole sketch in the future.
Anyway, there are three ways to fix this:
Option 1: Call the noSmooth() function.
By default, Processing uses anti-aliasing to make your drawings look smoother. Usually this is a good thing, but it can also add some fuzziness to the edges of shapes. If you disable anti-aliasing, your shapes will be more clear and you won't see the artifacts.
Option 2: Use a stroke with the same color as the fill.
As you've already discovered, this draws an outline around the shape.
Option 3: Use int values instead of float values.
You're storing your coordinates and sizes in float values, which can contain decimal places. The problem is, the screen (the actual pixels on your monitor) don't have decimal places (there is no such thing as half a pixel), so they're represented by int values. So when you convert a float value to an int, the decimal part is dropped, which can cause small gaps in your shapes.
If you just switch to using int values, the problem goes away:
size(1000, 100);
noStroke();
background(0);
int squareWidth = 10;
for(int squareX = 0; squareX < width; squareX += squareWidth){
rect(squareX, 0, squareWidth, height);
}

Processing Spacing

I'm trying to draw bears in processing, (Just simple circles), how can I get the bears equally spaced apart, and have the same space from the edge of the screen to the bears, on either side? As well as vertically.
I know this is vague, but I'm terrible at explaining things
Because you does not provide any code or example I will just tell you how to place circle in the middle of sketch.
For simplicity imagine this set up:
void setup(){
size(400, 400);
}
1) Very basic approach would be to hard code position of this circle into ellipse draw function.
ellipse(200, 200, 50, 50);
Where first two parameters are coordinates for circle center. Simple find out from size 400x400 that mid is on coord 200x200. This is bad approach and you should avoid using it.
2) Better approach would be to calculate center coord using global variables width and height
ellipse(width/2, height/2, 50, 50);
3) When you are drawing or moving more complex objects it is preferred to use some function to draw this objects always with same fixed position in our example
void draw_circle(){
ellipse(0, 0, 50, 50);
}
And just moving center of drawing using transformations so our draw function will looks like this
void draw(){
pushMatrix();
translate(width/2, height/2);
draw_circle();
popMatrix();
}
Using this you could be able to draw bears equally spaced apart and from sides.
It sounds like you want a grid of equally spaced circles. For that you just need to divide your space into a grid in the x and y directions. The simplest way to do this is to wrap the kind of thing Majlik showed inside a double loop to move from cell to cell in your 'virtual' grid. To see this more clearly, in the code below there is an extra little bit so that if you press the 'g' key (for grid) you'll see the grid cells, with a circle centered in each one. You can press any other key to make the grid go away.
You can see that each way gives the same result: inside draw() uncomment the one you want and comment out the other 2.
int nx = 4; // number of circles horizontally
int ny = 5; // number of circles vertically
int divx;
int divy;
int diameter = 40;
void setup() {
size(600, 600);
// calculate width and hegith of each cell of the grid
divx = width/nx;
divy = height/ny;
}
// 3 ways to draw a regular grid of circles
void draw() {
background(200);
// show the cell layout if the g key was typed, otherwise don't
if(key == 'g')
drawGrid();
// 1 way
for(int i = 0; i < nx; i++) {
for(int j = 0; j < ny; j++ ) {
ellipse(i * divx + divx/2, j * divy + divy/2, diameter, diameter);
}
}
// another way
// for(int i = divx/2; i < width; i += divx) {
// for(int j = divy/2; j < height; j += divy ) {
// ellipse(i, j, diameter, diameter);
// }
// }
// yet another way
// for(int i = divx/2; i < width; i += divx) {
// for(int j = divy/2; j < height; j += divy ) {
// pushMatrix();
// translate(i, j);
// ellipse(0, 0, diameter, diameter);
// popMatrix();
// }
// }
}
void drawGrid() {
// draw vertical lines
for(int i = 1; i < nx; i++) {
line(i * divx, 0, i * divx, height);
}
// draw horizontal lines
for(int j = 1; j < ny; j++ ) {
line(0, j * divy, width, j * divy);
}
}

Resources