The mythical "for" statements for noob like me...

What bothers me is the way how " for" statements are handled in nested iterations :

for (float x = 0 ; x< 400 ; x+= 40) {
    for (float y = 0 ; y< 400 ; y+= 40){
        shape
    }
}

I seem not to understand how the " for" starts

thus these mean that for every x becoming +40 it will create first y up to y 400 ? or

it has no sequence ? also how is the structure would be created if I added an inclining number after the encapsulated inclination ?

} insert something here with inclining variable the affect the shape in the encapsulated "for' structure }

what technique do you guys use to make using for iterations easy to predict the results ?

also is it possible to make many for inside for ?

Answers

  • edited June 2015 Answer ✓

    a single for-loop

    a single for-loop does something 10 times

    like drawing 10 rects one underneath the other

    x

    x

    x

    ....

    (like a list)

    a nested for-loop

    a double / nested for-loop says:

    • draw this one list 10 times. Because the inner for-loop is called 10 times by the outer for-loop.

    So you end up with a grid:

    x x x x x

    x x x x x

    x x x x x

    ....

    the inner loop is started completely anew every time, so each time x goes up by 40, y becomes 0 again and the complete inner loop (one list) is done.

    int cellSizeX = 16;
    int cellSizeY = 10;
    
    void setup() { 
      size(600, 600); 
      background(255);
      stroke(255, 2, 2); 
      fill(0);
    } // func
    
    void draw() {
      background(255); 
      for (int x = 0; x < 400/cellSizeX; x++) { 
        for (int y = 0; y < 400/cellSizeY; y++) { 
          rect(x*cellSizeX+12, y*cellSizeY+19, 
          cellSizeX, cellSizeY);
        } // for
      } // for
    } // func
    // 
    

    many for-loops

    you wrote :

    also is it possible to make many for inside for ?

    yes

    e.g. 3 nested for loops build a 3D grid like 8 chess boards in a stack one atop of the other.

    ;-)

  • thus these mean that for every x becoming +40 it will create first y up to y 400 ?

    Yes:

    x = 0, y = 0
    x = 0, y = 40
    x = 0, y = 80
    ...
    x = 40, y = 0
    x = 40, y = 40
    ...
    

    also how is the structure would be created if I added an inclining number after the encapsulated inclination ?

    What do you mean by that? Do you mean adding code after shape} and before the second } ? Then that would be just like a regular for loop over x, the y variable wouldn't even be defined there. What do you mean with inclining number?

  • In most situations, an int iterator is faster & safer than a float 1. :-B

  • edited June 2015
    for( [A]; [B]; [C] ){
      [D];
    }
    

    is the same as:

    [A];
    while( [B] ){
      [D];
      [C];
    }
    

    Maybe that helps.

  • edited June 2015

    yeah, this

     for (int x = 0; x < 400; x++) { 
             .......
     }
    

    means :

    • give x first the value 0.

    • Then do all in the section between { and }

    • then jump to { again and increase x by 1 (this is x++ ; can be another value)

    • Then do all in { and }

    • and so on - repeat

    repeat as long as x is smaller than 400.

    the part between { and }

    the part between { and } gets repeated

    in this part there can also be another, independent for-loop.

    ;-)

  • I get it a little but for you pro's how do you calculate and understand every calculation made ? What I mean how do you guys manage to understand every code and calculation made by complex maths involve and manage the results you want?

  • edited June 2015 Answer ✓

    the computer is doing your sketch step by step.

    he is doing it in a mathematical exact way.

    Therefore you can tell it exactly what it has to do.

    to understand it better

    to follow this there are different tactics:

    • you can insert println(x) in some lines:

      int cellSizeX = 16;
      int cellSizeY = 10;
      
      void setup() { 
        size(600, 600); 
        background(255);
        stroke(255, 2, 2); 
        fill(0);
        noLoop();
      } // func
      
      void draw() {
        background(255); 
        println ("Hey, I am println #0: just starting things up here ==== "); 
        for (int x = 0; x < 400/cellSizeX; x++) { 
          println ("Hey, I am println #1: x is " + x ); 
          for (int y = 0; y < 400/cellSizeY; y++) { 
            println ("Hey, I am println #2: x still is " + x + " and y is " + y ); 
            rect(x*cellSizeX+12, y*cellSizeY+19, 
            cellSizeX, cellSizeY);
          } // for
          println ("Hey, I am println #3: y for loop is done; x still is " + x ); 
        } // for
         println ("Hey, I am println #4: all done ============="); 
      } // func
      // 
      
    • you can follow the code line by line and just read it carefully and ask yourself, what he is the computer doing here

    • you can even take a pen and write it down like in a list: x is first 400; then he goes to the inner for loop and y being 0; then rect(); then y is 1 (and x still 400)

      round for the for loop x | x value | y value
      
      
      
        0                                  | 0          |    0 
        0                                  | 0          |    1 
        0                                  | 0          |    2 
        0                                  | 0          |    3
      ....
        1                                  | 1          |    0  
        1                                  | 1          |    1  
        1                                  | 1          |    2  
        1                                  | 1          |    3
      ...
        1                                  | 2          |    0  
        1                                  | 2          |    1  
        1                                  | 2          |    2  
        1                                  | 2          |    3
      
    • you can write a smaller version of you sketch that does only the part you are having trouble with - google mcve

    ;-)

  • P.S.

    what do you think is correct?

    • he is drawing the first line of rects and then he is drawing the 2nd line and so forth

    • he is doing the first column of rects and then the 2nd column.......

  • Answer ✓

    I think this example is fairly clear:

        int limit = 3;
        for (int i = 0; i< limit; i+=1) {
                println("i: " + i);
            for (int j = 0; j< limit; j+= 1){
                println("j: " + j);
                println("j: " + (j*40));
                println("index: " + (i*limit + j));
            }
        }
    

    i and j are more traditional loop variables ;)

    The following table shows output values of i going down the first column and of j going across from the 2nd column.

    i | j ->
    0 | 0 | 1 | 2
    1 | 0 | 1 | 2
    2 | 0 | 1 | 2

    So for each iteration of i (the outer loop) the inner will loop repeat 'limit' number of times; with values of i/j starting at zero. Obviously the inner loop can have a different limit if required.

    A single loop can be thought of as a 1 dimensional line. One loop nested inside another as 2 a dimensional plane measuring limit1 * limit 2. If limits for both loops are equal you have a square. A third nested loop gives you 3d space (size = limit1 * limit2 * limit3) and so on...

    Note that in a 2d loop (i * limit) + j returns the current 'index' of the combined loops - i.e. it counts from 0 to (limit1*limit2)-1.

    Also note that if you need to output bigger steps you can simply multiply the values of i/j. I find this more elegant and easier to read: I then know the size of the grid I'm generating (e.g. in this case 3 x 3) from the limit value in each loop. If you use bigger steps you have to do some simple, but tiresome, mental arithmetic to calculate the grid size...

    Save >1 steps for when you need to over-optimise...

  • edited June 2015 Answer ✓

    Another reason to favour steps of 1:

    To split any size of sketch into 'limit' number of columns (pseudo-code):

    int limit = n;
    float columnWidth = width/limit;
    
    for(int i=0; i<limit; i++) {
        float columnX = i * columnWidth;
    }
    

    Obviously the same principles - using a 2d loop - can be used to make a grid. You then don't have to worry about using values that can easily be added at each step (i.e. whole numbers), as in your original example; and don't have to make any adjustments, except to the sketch size, in order to render at a greater size.

  • Alright! thanks guys will do experiments with it

Sign In or Register to comment.