How to compile a series of functions into one variable?

edited October 2014 in How To...

Hello,

I am trying to write a code that will create a series of X along the sketch area. These X should form a grid where I can control the the vertical and horizontal gutter between them. Also, I would like to understand how can I compile the whole X code (stroke, strokeWeight, line) into one word such as xDraw.

Thank you in advance.

Here's the code so far:

int xSize;
int xWeight = 5;
int xNum = 10;
int xSpace = 50;

void setup() {

  size(500, 500);

  for (int i=0; i< xNum; i++) {
    strokeCap(SQUARE);
    strokeWeight(xWeight);
    line(20, 20, 40, 40);
    line(20, 40, 40, 20);

    if (i == i) {
      strokeCap(SQUARE);
      strokeWeight(xWeight);
      line(20+xSpace, 20, 40+xSpace, 40);
      line(20+xSpace, 40, 40+xSpace, 20);
    }
  }
}

Answers

  • You can define your own function.

    void setup(){
      size(500, 500);
      xDraw(5, 10, 50);
    }
    
    void xDraw(float xWeight, float xNum, float xSpace){
     for (int i=0; i< xNum; i++) {
        strokeCap(SQUARE);
        strokeWeight(xWeight);
        line(20, 20, 40, 40);
        line(20, 40, 40, 20);
    
        if (i == i) {
          strokeCap(SQUARE);
          strokeWeight(xWeight);
          line(20+xSpace, 20, 40+xSpace, 40);
          line(20+xSpace, 40, 40+xSpace, 20);
        }
      }
    }
    

    As an aside, I'm not sure what you intended with your line 16, but if (i == i) will always evaluate as true, because i is always equal to itself.

    Hope that helps.

  • edited April 2014

    you can make a class letter X

    and have a list of them

    (you could also use text() to write an 'X' )

    int xSize;
    
    int xNum = 10;
    int xSpace = 50;
    
    ArrayList<LetterX> lettersOfX = new ArrayList();
    
    void setup() {
    
      size(500, 500);
    
      // define all
      for (int i=0; i< xNum; i++) {
        LetterX currentLetterX=new LetterX();
        currentLetterX.posX=10+xSpace*i;
        currentLetterX.posY=10+xSpace*i;
        lettersOfX.add( currentLetterX );
      }
    }
    
    void draw() {
      // display all 
      for (LetterX currentLetterX : lettersOfX) {
        currentLetterX.display();
      }
    }
    
    // ==============================================
    
    class LetterX {
    
      int posX, posY;
      int xWeight = 5;
    
      // no constr
    
      void display() {
        strokeCap(SQUARE);
        strokeWeight(xWeight);
        line(posX+20, posY+20, posX+40, posY+40);
        line(posX+20, posY+40, posX+40, posY+20);
      }
    } // class 
    //
    
  • @velvetkevorkian Thanks dude. I am new to code and I don't practice enough to understand everything perfectly. On the line 16 I was trying to come with a solution to move the symbol along the xpos axis. Let's say that i2 xpos is the same as i1 xpos, then i2 will be moved to a new value. i understand the logic but I don't know how to translate in code. By the way, can you explain me the line below? Why are you using float for those int?

    void xDraw(float xWeight, float xNum, float xSpace)

    @Chrisir Thanks for the code dude. This is really going along the lines I want. please help me understand the code. Could you help me understand this two lines? I am struggling to understand the logic behind them.

    ArrayList<LetterX> lettersOfX = new ArrayList();

    for (LetterX currentLetterX : lettersOfX)

    I have tweaked your code a bit but I still having problems achieving my goal. I want to create a grid format using the X controlling the number of row and column in relation to the sketch size. I am not sure I am having the right logic though. Below I am trying to create a new line of X below the first one. It doesn't work and I am not sure this is the most practical solution. How can I solve this?

    Thanks again.

    Here's the code:

    int hSize= 500;
    int vSize = 500;
    
    int xNum = 50;
    int xSpace = hSize / xNum;
    
    ArrayList <SymbolX> symbolsOfX = new ArrayList();
    
    void setup() {
    
      size(hSize, vSize);
    
      // define all
      for (int i=0; i< xNum; i++) {
        SymbolX currentSymbolX = new SymbolX();
        currentSymbolX.posX = xSpace*i;
        symbolsOfX.add( currentSymbolX );
    
        if (currentSymbolX.posX > hSize) {
          for (int j=0; j< xNum; j++) {
            SymbolX currentSymbolY = new SymbolX();
            currentSymbolY.posY = 50+xSpace*i;
            symbolsOfX.add( currentSymbolY );
          }
        }
      }
    }
    
    void draw() {
      // display all 
      for (SymbolX currentSymbolX : symbolsOfX) {
        currentSymbolX.display();
      }
    }
    
    // ==============================================
    
    class SymbolX {
    
      int posX, posY;
      int xWeight = 1;
    
      // no constr
    
      void display() {
        strokeCap(SQUARE);
        strokeWeight(xWeight);
        line(posX+0, posY+0, posX+20, posY+20);
        line(posX+20, posY+0, posX+0, posY+20);
      }
    } // class 
    //
    
  • ArrayList<LetterX> lettersOfX = new ArrayList();

    Actually, since the number of entries is a fixed 10 - int xNum = 10;, there would be no need to bother using an ArrayList!
    A regular array would be enough - LetterX[] lettersOfX = new LetterX[xNum];

    http://processing.org/reference/Array.html
    http://processing.org/reference/ArrayList.html

  • edited April 2014

    for (LetterX currentLetterX : lettersOfX) {}

    That is called enhanced or for each loop!
    It iterates over each element of lettersOfX, extracting them to currentLetterX variable on each iteration.

  • this gives you a grid:

    int xSize;
    
    int xNum = 5;
    int xSpace = 50;
    
    ArrayList<LetterX> lettersOfX = new ArrayList();
    
    void setup() {
    
      size(500, 500);
    
      // define all
      for (int i=0; i< xNum; i++) {
        for (int j=0; j< xNum; j++) {
    
          LetterX currentLetterX=new LetterX();
          currentLetterX.posX=10+xSpace*i;
          currentLetterX.posY=10+xSpace*j;
          lettersOfX.add( currentLetterX );
        }
      } // for
    } // func 
    
    void draw() {
      // display all 
      for (LetterX currentLetterX : lettersOfX) {
        currentLetterX.display();
      }
    }
    
    // ==============================================
    
    class LetterX {
    
      int posX, posY;
      int xWeight = 5;
    
      // no constr
    
      void display() {
        strokeCap(SQUARE);
        strokeWeight(xWeight);
        line(posX+20, posY+20, posX+40, posY+40);
        line(posX+20, posY+40, posX+40, posY+20);
      }
    } // class 
    //
    
  • ArrayList

    ArrayList is a special list.

    in the list there are items.

    you can easily add an item using add (line 19)

    Each item is an object LetterX - it has an position and an strokeWeight xWeight. It could also have a color. It is a package with properties (like position etc.) and functions (like display()).

    also you can go through all it's elements by the for-loop (line 26) as gotoloop explained

    grid

    the way we achieve the grid is a double for-loop: for each column i we loop through all the rows j

    we then use i and j to define a position of each X

  • edited April 2014

    this

    ArrayList<LetterX> lettersOfX = new ArrayList();
    

    says

    invoke a new ArrayList of the name lettersOfX (what you need later in your code) and the items in it are of type LetterX

    LetterX you defined yourself as a class

    it's a list of items of LetterX

    when we say

    LetterX currentLetterX=new LetterX();
    

    (line 16) we have a single item we can work with it.

    We can then bring it into the list (line 19) using add()

    similar in line 27 we get one item from the list and display it using display().

  • @Chrisir, @GoToLoop Thank you for your help. I am understanding better the logic behind the code. Now with the grid in place I am trying to create an Array with 3 colours that will be assigned randomly to the stroke(). I tried a few things with the code but no success. What I am doing wrong?

    Thanks again.

    Here's the latest code:

    import processing.pdf.*;
    boolean savePDF = false;
    
    int hSize= 500;
    int vSize = 500;
    int xWeight = 30;
    
    int xNum = 25;
    int xSpace = 20;
    
    int[] c = new int[3]; // Array colours
    c[0] color = 0xFFCC00;
    c[1] color = 0xFF9900;
    c[2] color = 0xFF35EE;
    
    ArrayList <SymbolX> symbolsOfX = new ArrayList();
    
    void setup() {
    
      size(hSize, vSize);
    
      // define all
      for (int i=0; i < xNum; i++) {
        for (int j=0; j < xNum; j++) {
    
          stroke(c[0]); // Default colour?
    
          SymbolX currentSymbolX = new SymbolX();
          currentSymbolX.posX = xSpace*i;
          currentSymbolX.posY = xSpace*j;
          symbolsOfX.add( currentSymbolX );
        }
      }
        if ( savePDF ) { // Begin record 
        beginRecord( PDF, "pdf/myartwork-####.pdf" );
      }
    
      // display all 
      for (SymbolX currentSymbolX : symbolsOfX) {
        currentSymbolX.display();
      }
       if ( savePDF ) { // End record
        endRecord(); 
        savePDF = false;
      }
    }
    
    // ==============================================
    
    class SymbolX {
    
      int posX, posY;
    
      void display() {
    
        if (stroke(c[0]) { // Colours randomizer
          stroke(c[1]);
        }
         else if (stroke(c[1]) {
          stroke(c[2]);
        }
         else if (stroke(c[2]) {
          stroke(c[0]);
        }
    
        strokeCap(SQUARE);
        strokeWeight(xWeight);
        line(posX+0, posY+0, posX+20, posY+20);
        line(posX+20, posY+0, posX+0, posY+20);
      }
    }
    
    
    void keyPressed() {
      if ( key == 's' ) {
        savePDF = true;
      }
    }
    
  • here

    int xSize;
    
    int xNum = 5;
    int xSpace = 50;
    
    ArrayList<LetterX> lettersOfX = new ArrayList();
    
    color [] c = new int[3]; // Array colours
    
    void setup() {
    
      size(500, 500);
    
      c[0] =color  ( 255, 2, 2);
      c[1] =color  ( 2, 255, 2);
      c[2] =color  ( 2, 2, 255);
    
    
      // define all
      for (int i=0; i< xNum; i++) {
        for (int j=0; j< xNum; j++) {
    
          LetterX currentLetterX=new LetterX();
          currentLetterX.posX=10+xSpace*i;
          currentLetterX.posY=10+xSpace*j;
          currentLetterX.col1=c[ int (random(3))   ];
          // currentLetterX.col1=111;
          lettersOfX.add( currentLetterX );
        }
      } // for
    } // func 
    
    void draw() {
      // display all 
      for (LetterX currentLetterX : lettersOfX) {
        currentLetterX.display();
      }
    }
    
    // ==============================================
    
    class LetterX {
    
      int posX, posY;
      int xWeight = 5;
      color col1; 
      // no constr
    
      void display() {
        strokeCap(SQUARE);
        strokeWeight(xWeight);
        stroke (col1);
        line(posX+20, posY+20, posX+40, posY+40);
        line(posX+20, posY+40, posX+40, posY+20);
      }
    } // class 
    //
    
  • your lines 11 to 14 I had to rewrite

    since the color of the X is also a property of X, the idea is to put the color into the class (line 46 / 52) and define it at the beginning like the other properties (line 26)

    you might want to read the tutorial on classes / OOP:

    https://forum.processing.org/tutorials/objects

    or read the first 6 tutorials :

    https://forum.processing.org/tutorials

    Greetings, Chrisir ;-)

  • your Colours randomizer

    is in my line 26

  • edited September 2019 Answer ✓

    Here's my own tweak-ish take on it: :bz

    /**
     * Letters-X (v3.1)
     * by  DiegoOriani (2014/Apr)
     * mod Chrisir & GoToLoop
     *
     * Forum.Processing.org/two/discussion/4275/
     * how-to-compile-a-series-of-functions-into-one-variable#Item_13
     */
    
    import processing.pdf.PGraphicsPDF;
    
    interface DataX {
      int ROWS = 8, COLS = 10, GAP = 030, MARGIN = 020;
      int LEN = 030, WEIGHT = 5, CAP = SQUARE;
    
      int HSIZE = COLS*(LEN+GAP) + MARGIN*2 - GAP;
      int VSIZE = ROWS*(LEN+GAP) + MARGIN*2 - GAP;
    
      color BG = 0300;
    
      color[] inks = {
        //#FFCC00, #FF9900, #FF35EE
        #FF0000, #008000, #0000FF
      };
    
      String PDF_FILE = "lettersX-####.pdf";
    }
    
    final LetterX[] xxx = new LetterX[DataX.ROWS * DataX.COLS];
    boolean savePDF;
    
    void settings() {
      size(DataX.HSIZE, DataX.VSIZE);
    }
    
    void setup() {
      if (width != DataX.HSIZE | height != DataX.VSIZE)  settings();
    
      noLoop();
      frameRate(10);
    
      initCanvas();
      instantiateLettersX();
    
      println("Width: " + width + "\tHeight: " + height);
      println("# of Xs: " + xxx.length + "\n");
    }
    
    void initCanvas() {
      smooth();
      background(DataX.BG);
      strokeWeight(DataX.WEIGHT);
      strokeCap(DataX.CAP);
    }
    
    void draw() {
      if (savePDF) {
        beginRecord(PDF, dataPath(DataX.PDF_FILE));
        initCanvas();
      }
    
      for (LetterX currentX : xxx)  currentX.display();
    
      if (savePDF) {
        endRecord();
        savePDF = false;
        println("Frame #" + frameCount + " saved!");
      }
    }
    
    void keyPressed() {
      reshuffleInks();
      redraw = true;
      if (keyCode == 'S')  savePDF = true;
    }
    
    void mousePressed() {
      keyCode = 0;
      keyPressed();
    }
    
    void reshuffleInks() {
      for (final LetterX currentX : xxx)
        currentX.c = DataX.inks[(color) random(DataX.inks.length)];
    }
    
    void instantiateLettersX() {
      for (int r = 0; r < DataX.ROWS; ++r)  for (int c = 0; c < DataX.COLS; ++c) {
        final int x = c*(DataX.LEN + DataX.GAP) + DataX.MARGIN;
        final int y = r*(DataX.LEN + DataX.GAP) + DataX.MARGIN;
        final color ink = DataX.inks[(color) random(DataX.inks.length)];
    
        xxx[r*DataX.COLS + c] = new LetterX(x, y, ink);
      }
    }
    
    class LetterX implements DataX {
      final short x, y;
      color c;
    
      LetterX(int xx, int yy, color cc) {
        x = (short) xx;
        y = (short) yy;
        c = cc;
      }
    
      void display() {
        stroke(c);
        line(x, y, x+LEN, y+LEN);
        line(x+LEN, y, x, y+LEN);
      }
    }
    
  • @Chrisir, Thanks for the patience buddy. Your explanations are really useful. I will check the links and see if I can understand better classes / OOP.

    @GoToLoop, Thanks dude, I really like the way everything seems more dynamic now. It will take me while to understand what you did there but I really appreciate the help.

  • edited September 2019

    A little variation of the theme. Instead of defining a custom LetterX class, this 1 relies on Processing's own built-in 1 called PVector!
    PVector already got 3 float fields: x, y, z.
    Fields x & y will take the role of the coordinate pair.
    While z gonna store the ink!
    Then, the former LetterX's display() method becomes sketch's display(PVector p) top-class function! :D

    /**
     * Letters-X w/ PVector (v1.1)
     * by  DiegoOriani (2014/Apr)
     * mod Chrisir & GoToLoop
     *
     * Forum.Processing.org/two/discussion/4275/
     * how-to-compile-a-series-of-functions-into-one-variable#Item_15
     */
    
    import processing.pdf.PGraphicsPDF;
    
    interface DataX {
      int ROWS = 8, COLS = 10, GAP = 030, MARGIN = 020;
      int LEN = 030, WEIGHT = 5, CAP = SQUARE;
    
      int HSIZE = COLS*(LEN+GAP) + MARGIN*2 - GAP;
      int VSIZE = ROWS*(LEN+GAP) + MARGIN*2 - GAP;
    
      color BG = 0300;
    
      color[] inks = {
        //#FFCC00, #FF9900, #FF35EE
        #FF0000, #008000, #0000FF
      };
    
      String PDF_FILE = "lettersX-####.pdf";
    }
    
    final PVector[] xxx = new PVector[DataX.ROWS * DataX.COLS];
    boolean savePDF;
    
    void settings() {
      size(DataX.HSIZE, DataX.VSIZE);
    }
    
    void setup() {
      if (width != DataX.HSIZE | height != DataX.VSIZE)  settings();
    
      noLoop();
      frameRate(10);
    
      initCanvas();
      instantiateLettersX();
    
      println("Width: " + width + "\tHeight: " + height);
      println("# of Xs: " + xxx.length + "\n");
    }
    
    void initCanvas() {
      smooth();
      background(DataX.BG);
      strokeWeight(DataX.WEIGHT);
      strokeCap(DataX.CAP);
    }
    
    void draw() {
      if (savePDF) {
        beginRecord(PDF, dataPath(DataX.PDF_FILE));
        initCanvas();
      }
    
      for (final PVector currentX : xxx)  display(currentX);
    
      if (savePDF) {
        endRecord();
        savePDF = false;
        println("Frame #" + frameCount + " saved!");
      }
    }
    
    void display(PVector p) {
      stroke((color) p.z);
      line(p.x, p.y, p.x+DataX.LEN, p.y+DataX.LEN);
      line(p.x+DataX.LEN, p.y, p.x, p.y+DataX.LEN);
    }
    
    void keyPressed() {
      reshuffleInks();
      redraw = true;
      if (keyCode == 'S')  savePDF = true;
    }
    
    void mousePressed() {
      keyCode = 0;
      keyPressed();
    }
    
    void reshuffleInks() {
      for (final PVector currentX : xxx)
        currentX.z = DataX.inks[(color) random(DataX.inks.length)];
    }
    
    void instantiateLettersX() {
      for (int r = 0; r < DataX.ROWS; ++r)  for (int c = 0; c < DataX.COLS; ++c) {
        final int x = c*(DataX.LEN + DataX.GAP) + DataX.MARGIN;
        final int y = r*(DataX.LEN + DataX.GAP) + DataX.MARGIN;
        final color ink = DataX.inks[(color) random(DataX.inks.length)];
    
        xxx[r*DataX.COLS + c] = new PVector(x, y, ink);
      }
    }
    
  • The following program totally does not work, but couldn't a simple grid with 'X's have been accomplished by using embedded for loops? Something like this:

    void setup() {
      size(500, 500);
    }
    
    void draw() {
      for (int x1 = 20; x1 <= (width-20); x1+=50) {
        for (int y1 = 20; y1 <= (height-20); y1+=50 ) {
          for (int x2 = 40; x2 <= (width-20); x2+=50) {
            for (int y2 = 40; y2 <= (height-20); y2+=50) {
              background(255);
              strokeCap(SQUARE);
              strokeWeight(5);
              line(x1, y1, x2, y2);
              line(x1, y1+20, x2, y2-20);
              }
            }
          }
        }
    }
    

    Again, this program totally does not do what I wanted it to do lol. However, couldn't something like this be done building on our basic knowledge of Processing that we have acquired thus far without jumping months ahead of our own experience?

    • @Bilvad, @ line #10, you're clearing the canvas bazillion times over! >:)
    • Moreover, if you got something fixed, that doesn't change inside a loop, place it before it!
    • Lines #11 & #12 doesn't change and are redundant and making the sketch slow.
    • Even better, place them within setup()! :P
  • edited April 2014

    @ Bilvad :

    you wrote :

    couldn't a simple grid with 'X's have been accomplished by using embedded for loops

    here

    int xSize;
    
    int xNum = 5;
    int xSpace = 50;
    
    color [] c = new int[3]; // Array colours
    
    void setup() {
    
      size(500, 500);
    
      c[0] =color  ( 255, 2, 2);
      c[1] =color  ( 2, 255, 2);
      c[2] =color  ( 2, 2, 255);
    } // func 
    
    void draw() {
    
      // draw all
      for (int i=0; i< xNum; i++) {
        for (int j=0; j< xNum; j++) {
    
          int posX=10+xSpace*i;
          int posY=10+xSpace*j;
    
          stroke(c[ int(random( c.length )) ]);
    
          line(posX+20, posY+20, posX+40, posY+40);
          line(posX+20, posY+40, posX+40, posY+20);
        }
      } // for
    }
    
    // =============================================
    

    you wrote

    couldn't something like this be done building on our basic knowledge of Processing that we have acquired thus far without jumping months ahead of our own experience?

    your initial question was quote "a series of functions into one variable?" unquote. That's what a class is in a way.

    I think you are intelligent enough to figure out the code we gave you, right?

    So just make it part of your own experience...

    ;-)

Sign In or Register to comment.