For my Computer Graphics art recreation project (see on the top below), I decided to attempt to faithfully recreate the following image (on the bottom below) from the 1978 issue of Computer Graphics and Art:
I started out my project with a relatively clear idea of how to recreate the increasing density of the filling lines of the pattern, recreating the image proved a lot more time consuming than I thought, and I also ended up with a still imprecise version.
My very first attempt began with creating the horizontal-lined boxes and then vertical-lined boxes in between them, but I realized it is much more meaningful to interpret the image as a number of boxes with horizontal line pattern on top of a vertical line patterned background. So as a first step, I wrote a function for filling the background with an increasing density of the lines. However, even though I spent a lot of time searching for the most optimal method and definition of distance between the lines, the transition from the low density to the high density part of the pattern is still uneven.
To be able to place the rectangles as in the original picture, I needed to create a grid of the image (see initial stage below) and look for the coordinates of the start and endpoints of the rectangles (which was the factor that made the project a lot longer than I expected).
I stored the data of the coordinates in 4 arrays (for the lists of the start and end x and y coordinates), which I used in a function that draws a line-filled rectangle. The function decides on the density of the line pattern based on the start y coordinates of the rectangle, that is, based on its location in the image, and it gets less and less dense as the rectangle is closer and closer to the bottom.
Lastly, to make the image flexible to change, I included loop that maps the original coordinates of the image to be proportional to whatever size is defined at the setup (although in my code, I kept the original size of the image).
You can see my code here:
float[] exesOrig={137.5,225,290,340,382,420,450,480,505,530, 547,567,587,605,615,635,647,660,675,685, 697,707,720,730,737,750,758,767,775,780, 790,797,806,812,818,825}; // original division of the widht of the image float[] whysOrig={20,42,70,100,140,180,235, 297,385}; // original division of the height of the image float[] exes = new float[38]; float[] whys = new float[11]; int once=0; int[] xBegin = {35, 28, 30, 31, 33, 32, 34, 35, 29, 30, 30, 37, 0, 2, 4, 1, 2, 33, 0, 1, 3, 37, 0, 4, 4, 6, 7, 9, 5, 5, 9, 2, 6, 6, 8, 11, 10, 11, 10, 9, 11, 11, 13, 14, 14, 16, 15, 14, 15, 16, 18, 18, 19, 18, 18, 13, 16, 16, 18, 18, 23, 23, 25, 20, 21, 22, 21, 22, 24, 24, 21, 22, 23, 28, 24, 25, 26, 25, 25, 27, 31, 33, 27, 29, 31, 30, 32, 34, 35}; int[] yBegin = {10, 10, 10, 1, 10, 4, 4, 3, 3, 2, 1, 10, 10, 0, 10, 1, 2, 2, 3, 4, 5, 5, 6, 2, 3, 0, 10, 3, 4, 5, 6, 8, 6, 7, 8, 7, 8, 10, 0, 1, 3, 4, 2, 4, 5, 4, 3, 0, 10, 0, 10, 0, 1, 2, 3, 7, 6, 8, 7, 6, 7, 8, 8, 4, 5, 10, 0, 1, 0, 1, 3, 4, 5, 2, 2, 3, 4, 5, 6, 8, 8, 8, 5, 6, 5, 7, 7, 7, 5}; int[] xEnd = {36, 29, 32, 32, 34, 33, 35, 36, 34, 31, 34, 0, 2, 5, 5, 3, 3, 36, 1, 3, 4, 0, 5, 5, 7, 7, 8, 10, 10, 12, 13, 7, 7, 8, 9, 12, 11, 13, 11, 13, 12, 13, 14, 15, 18, 18, 16, 15, 17, 17, 20, 19, 20, 22, 20, 15, 17, 20, 19, 24, 28, 24, 26, 21, 22, 25, 23, 23, 25, 29, 23, 24, 24, 29, 27, 28, 28, 26, 28, 30, 32, 34, 30, 33, 32, 31, 33, 36, 36}; int[] yEnd = {1, 1, 0, 2, 0, 5, 5, 4, 4, 3, 2, 2, 0, 1, 1, 2, 3, 3, 4, 5, 6, 6, 7, 3, 4, 3, 0, 4, 5, 6, 7, 9, 7, 8, 9, 8, 9, 0, 1, 2, 4, 5, 4, 5, 6, 5, 4, 2, 0, 3, 0, 1, 2, 3, 4, 8, 8, 9, 8, 7, 8, 9, 9, 5, 6, 0, 1, 2, 1, 2, 4, 5, 6, 3, 3, 4, 5, 6, 7, 9, 9, 9, 6, 7, 6, 8, 8, 8, 7}; void setup() { size(835,510); strokeWeight(1.2); exes[36] = width; exes[37] = 0; whys[9] = height; whys[10] = 0; for(int i=0; i<36; i++) { exes[i]= (exesOrig[i]/835)*width; } //set division of the width of the reproduced image proportional to the original one for(int i=0; i<9; i++) { whys[i]= (whysOrig[i]/510)* height; } //set division of the width of the reproduced image proportional to the original one background(255); fill(0); } void draw() { if (once==0){bgLines();} else {bgSquares();} } void bgSquares() { noStroke(); fill(255); for(int i =0; i<89; i++) { vertRect(exes[xBegin[i]], whys[yBegin[i]], exes[xEnd[i]], whys[yEnd[i]]); } } void vertRect(float x, float y, float x2, float y2) { float[] distanceArray = {whys[0]*1.2, whys[0]*0.75, whys[0]*0.5, whys[0]*0.4, whys[0]*0.25, whys[0]*0.2, whys[0]*0.2, whys[0]*0.15, whys[0]*0.15 }; //keeping the spaces proportional to the other measurements, as in the original image noStroke(); int j=8; fill(255); rect(x, y, x2-x, y2-y); while (y<y2) { strokeWeight(1.2); stroke(0); line(x, y, x2, y); for(int i=0; i<9; i++) { if(y==whys[i]) { j=8-i; i=9; } } y+=distanceArray[j]; } } void bgLines() { int x=1; int i=0; float[] distanceArray = {whys[0]*1.2, whys[0]*0.75, whys[0]*0.5, whys[0]*0.4, whys[0]*0.25, whys[0]*0.25, whys[0]*0.15, whys[0]*0.15, whys[0]*0.15, whys[0]*0.1, whys[0]*0.1, whys[0]*0.1, whys[0]*0.1 }; //keeping the spaces proportional to the other measurements, as in the original image float distance = distanceArray[0]; float change=.95; float temp; while(x<width) { line(x, 0, x, height); x+=distance; if (x>=exes[i]) { if(i<35) { i+=1; } if(i==1 || i==2){ distance=distanceArray[i]; } if(i>2 &&i<23 && i%2==1){ distance=distanceArray[(i+3)/2];} } if (i!=0 && ((distance*0.9999)>.5)) {temp=distance; println(temp); distance=temp-(i/10000); println(distance);} if( x+distance > width) {x=width; once=1;} } }