KelseyLee-13-9-65

by kelsey @ 3:42 am 23 January 2012

 

Using Processing, I tried to replicate the piece 13/9/65 Nr. 2, by Frieder Nake . By storing all of the points in arrays to access later, I was able to slow down the output so that you can see each line being drawn.

/*
 *Kelsey Lee 13/9/65 Nr. 2, by Frieder Nake (born 1938, Germany)
 *trying to replicate  13/9/65 Nr. 2, by Frieder Nake (born 1938, Germany)
 *randomly selects widths of columns
 *randomly selects where to place horizontal lines, width of segments & incline/decline of those segments
 *will then chose whether the block created by the column/horizontal line barriers should contain 
 *straight lines, triangles/angles or nothing - if trianlges will choose whether to originate from top or bottom
 *when done, will randomly select number of circles, radius of circles and placement of circles
 *
 *  ***will draw it line by line so you can see process***
 */
 
int WIN_WIDTH = 600;
 
int COLS;
int CUBE_WIDTH_MIN = 30;
int CUBE_WIDTH_MAX = 80;
 
int[]colSegments = new int[int(WIN_WIDTH/CUBE_WIDTH_MIN)+1];
 
horizLine startHorizLine;
horizLine endHorizLine;
horizLine screenBottom;
 
vertLineHolder vertHolder;
vertLineSeg vertSeg;
 
int ctr;
int horizCtr;
int yHeight;
int circleCtr;
int numCircles;
 
String phase;
boolean moreVert;
boolean lastLine;
 
int CUBE_HEIGHT_START_MIN = 60;
int CUBE_HEIGHT_START_MAX = 100; //prior to sloping lines up or down
 
void setup(){
  size(WIN_WIDTH, WIN_WIDTH); //create window
  stroke(0);
  strokeWeight(1.5);
  smooth();
  background(255); 
  frameRate(40);
   yHeight =  0;
   lastLine = false;
 
   startHorizLine = new horizLine(0);
   startHorizLine.createTop();
 
   screenBottom = new horizLine(WIN_WIDTH);
   screenBottom.createBottom();
 
   //find column widths
   colSegments[0] = int(random(CUBE_WIDTH_MIN,CUBE_WIDTH_MAX)); //generates first cube width
   ctr=1;
   COLS=0;
   //randomly chose width of column until nearly at edge of screen, make sure last column is at least min cube width
   while ((colSegments[ctr-1]+CUBE_WIDTH_MIN)  endHorizLine.numPts) {
           phase="startVertSeg";
        }
    }  
    else if (phase == "startVertSeg") {
        vertHolder = new vertLineHolder(startHorizLine, endHorizLine);
        moreVert = vertHolder.drawLine();
        phase = "continueVertSeg"; 
    }
    else if (phase == "continueVertSeg") {
       moreVert = vertHolder.drawLine();
       if (moreVert == false) {
        // print("end vert seg\n");
         phase = "endVertSeg"; 
       }
    }
    else if (phase == "endVertSeg") {
       phase = "endHorizLineBegin";
       startHorizLine = endHorizLine; //now the bottom horizontal line is the starting horizontal line for the next iteration
       yHeight += int(random(int(WIN_WIDTH/10),int(WIN_WIDTH/8))); //choose starting height of the next line 
       if (lastLine == true) {
        phase = "circles"; 
       }
       if((yHeight+CUBE_HEIGHT_START_MAX+(CUBE_HEIGHT_START_MAX/5)) >= WIN_WIDTH) {
          lastLine = true;
       }
    }
    else if (phase == "circles") {
      boolean endOfCircles = makeCircles(); // draw circles
      if (endOfCircles == true) {
        phase="completed";
      }
  }
 
  if (phase == "completed"){
    noLoop();
  }
}
 
 
 
//make line equation from horizontal line of points and plug in known xVal to find the yVal
float findYVal(int xVal, int[][]horizLine) {
   int ctr = 0;
   boolean foundY = false;
   float yVal =0;
 
  //find which column this xVal is in
  while (foundY == false) {
    //if true, xVal is in this column
     if (xVal >=  horizLine[ctr][0] && xVal <= horizLine[ctr][2]) {  
       //line eq, plug in x 
       yVal = float(horizLine[ctr][3]-horizLine[ctr][1])/float(horizLine[ctr][2]-horizLine[ctr][0])*float(xVal-horizLine[ctr][2]) +horizLine[ctr][3];
       foundY=true;
      }
      else {
        ctr++; 
      }
  }
  return yVal;
}
 
/* 
 * structure that holds a whole row's worth of vertical line segments
 * keeps track of which segment is being drawn & which line in that segment is being drawn.
 * creates many vertLineSeg structures which contain the points of all vertical lines to be drawn
 */
class vertLineHolder{
  vertLineSeg[] segs = new vertLineSeg[COLS]; //holds vertical line segments
  horizLine startLine; 
  horizLine endLine;
  int col; //for total number of columns
  int currentCol; //used later to iterate through all columns
  int currentLine; //keeps track of which line in a segment is being drawn
 
  //constructor
  vertLineHolder(horizLine startHorizLine, horizLine endHorizLine){
      startLine = startHorizLine;
      endLine = endHorizLine;
      col = 0; 
      int vertLineStart = 0;
      currentCol = 0;
 
      //now create segments for whole row; randomize type of vertical lines for segment
      while (colSegments[col+1] < WIN_WIDTH) {
       // print("col: " +col);
         int vertLineEnd = colSegments[col];
 
         int pattern = int(random(0,8)); //0,1 -vert lines; 2,3 - triangles, 4-8 -empty makes it  5/8ths likely that nothing will be drawn
         //when creating vertLineSeg, call that constructor to choose lines
         if (pattern  segs[currentCol].numLines-1) {
      //  print("from check to next col update col \n\n");
         currentLine=0;
         currentCol+=1; 
      }
    }
 
    //if now onto a column that exceeds the number of columns present, then must go to next row to draw
    if (currentCol >= COLS) {
   //   print("resetCol \n");
        currentCol = 0;
       return false; //meaning row is done being drawn
    }
    else {
      return true; //row is not done being drawn
    }
  }
}
 
 
//a single segment of vertical lines
class vertLineSeg {
  int numLines;
  int type; //type of lines
  int vertSeg;
  int vertStart; // value of starting x
  int vertEnd; // valiue of ending x
  float [][]segPts; // array of points for this segment
  int currentLine; //current line being drawn
 
 
   vertLineSeg(horizLine startHorizLine, horizLine endHorizLine, int t, int vertLineStart, int vertLineEnd) {
      type = t; // for straight or angled lines
      vertSeg = 0;
      vertStart = vertLineStart; // value of starting X
      vertEnd = vertLineEnd; //value of ending X
 
      currentLine =0; //current Line being created
 
      int lineCtr = 0; // the line being drawn
      numLines = int(random(1,(vertEnd-vertStart)/6)); //arbitrary 6 - total number of lines/angles for this seg,ent
 
      segPts = new float[(numLines*2)][4]; //array of points
 
 
 
      if (type == 1) { // straight lines
      //print(" lines: " + numLines + " | ");
       while (lineCtr  WIN_WIDTH) {
               startXVal=WIN_WIDTH;  //don't draw past end of screen
          }
          float yValStart = findYVal(startXVal, startHorizLine.horizPts);
          float yValEnd = 0;
 
          yValEnd = findYVal(startXVal, endHorizLine.horizPts);
          //store values
          segPts[lineCtr][0] = segPts[lineCtr][2] = startXVal;
          segPts[lineCtr][1] = yValStart;
          segPts[lineCtr][3] = yValEnd;
          lineCtr+=1; //increment to create next line
       }
 
      }
      else if (type==2) { //create angles starting from top
        numLines *=2;  // will need to store double the amount of lines b/c 2 lines for angle
     //   print(" lines: " + numLines + " | ");
        while ((lineCtr+2)  WIN_WIDTH) {
               startXVal=WIN_WIDTH;  //don't draw past end of screen
          }
          float yValStart = findYVal(startXVal, startHorizLine.horizPts);
          float yValEnd = 0;
          //create both lines of angle
          for (int i=0; i WIN_WIDTH) {
                   endXVal=WIN_WIDTH; 
               }    
                yValEnd = findYVal(endXVal, endHorizLine.horizPts);
 
                segPts[lineCtr][0] = startXVal;
                segPts[lineCtr][1] = yValStart;
                segPts[lineCtr][2] = endXVal;
                segPts[lineCtr][3] = yValEnd;
                lineCtr+=1;
          }
       }
      }
      else if (type == 3) { // create angles starting from bottom
        numLines *=2; 
     //   print(" lines: " + numLines + " | ");
        while ((lineCtr+2)  WIN_WIDTH) {
               startXVal=WIN_WIDTH;  //don't draw past end of screen
          }
          float yValStart = findYVal(startXVal, endHorizLine.horizPts);
           float yValEnd = 0;
          for (int i=0; i WIN_WIDTH) {
                   endXVal=WIN_WIDTH; 
               }    
               yValEnd = findYVal(endXVal, startHorizLine.horizPts); //ending yVals are on the top horizontal line
 
                segPts[lineCtr][0] = startXVal;
                segPts[lineCtr][1] = yValStart;
                segPts[lineCtr][2] = endXVal;
                segPts[lineCtr][3] = yValEnd;
                lineCtr+=1;
          }
        }
      }
 //  print( "\n");
 } 
}
 
//creates a horizontal line
class horizLine {
   int[][]horizPts = new int[10][4]; // stores points for horiz line
   int numPts;
   int minStartY; // starting Y
   int horizCtr; //number of horiz segments
 
   horizLine (int y){
      numPts = 0;
      minStartY = y;
      horizCtr=0;
   } 
 
   //line for top of screen
   void createTop() {
     horizPts[0][0] = horizPts[0][1] = horizPts[0][3] = 0;
     horizPts[0][2] = WIN_WIDTH;
   }
 
   //line for bottom of screen
   void createBottom() {
     horizPts[0][0]= 0;
     horizPts[0][1] = horizPts[0][2] = horizPts[0][3] = WIN_WIDTH;
   }
 
   // all other lines
   void createLine(){
     int remainingWidth = WIN_WIDTH;
 
      //starting coordinate
      int startX=0; 
      int startY = minStartY + int(random(CUBE_HEIGHT_START_MIN ,CUBE_HEIGHT_START_MAX));
 
      //line can slope up or down only w/in the following range - so as not to allow the horizontal lines to intersect with each other
      int minY = startY - ((startY-minStartY)/5); 
      int maxY = startY + ((startY-minStartY)/5);
      numPts = 0;
      while (remainingWidth > 0) {
        //find ending point for hte line segment
        int endX = startX + int(random(CUBE_HEIGHT_START_MIN ,CUBE_HEIGHT_START_MAX));
        //if chosen end X coordinate is past the end of the screen, reset to end of screen
        if (endX > WIN_WIDTH || (endX+CUBE_WIDTH_MIN)>WIN_WIDTH) {
          endX = WIN_WIDTH;
         }
         //will this segment of line slope up (0) or down (1)
         int sign = int(random(0,1));
         int endY;
         if (sign == 0 ) {
           endY = int(random(minY, maxY));
          }
          else {
            endY = -1*int(random(minY, maxY));
          }
          //store that line segment
          horizPts[numPts][0] = startX;
          horizPts[numPts][1] = startY;
          horizPts[numPts][2] = endX;
          horizPts[numPts][3] = endY;
          numPts+=1;
 
          remainingWidth = WIN_WIDTH - endX;
          ctr+=1;
          //end point from previous segment becomes the start of the next
          startX = endX;
          startY = endY;
        }
       }
 
       int[][] getLine() {
          return horizPts; 
       }
 
}
 
 
//draw circles, xVal of center will fall inside a column
boolean makeCircles() {
  fill(255, 0);
 
  //randomly choose number of circles
 
  if (circleCtr < numCircles) {
    //randomly choose radius
    int circleRadius = int(random(CUBE_WIDTH_MIN,200))/2;
    int cubeNum  = int(random(1,COLS));
    int xCoord= int(random(colSegments[cubeNum-1],colSegments[cubeNum]));
    ellipse(xCoord, int(random(circleRadius,WIN_WIDTH-circleRadius)), circleRadius, circleRadius);
    circleCtr++;
  } 
  else {
   return true; 
  }
  return false;
}

This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License.
(c) 2023 Interactive Art and Computational Design, Spring 2012 | powered by WordPress with Barecity