For loop matrix index

int total;
float itemSize;

void setup() {
  size(800, 800); 
  pixelDensity(2);
  smooth();
  rectMode(CENTER);

  total = 4;
  itemSize = width/total;
}

void draw() {
  clear();
  for (int i = 0; i < sq(total); i ++) {
    float x = i % total * itemSize + itemSize/2;
    float y = i / total * itemSize + itemSize/2;
    fill(-1);
    square(x, y, itemSize * 0.8);

    fill(0);
    textSize(40);
    text(i+1, x, y);
  }
}

Currently I can do this step, but there is no way to sort it in reverse order.

This is my attempt, for (int i = sq(total); i >= 0; i --) {} is there something wrong with my calculation method?

How do I achieve the flashback effect in the schematic, please?

Thank you so much for your help!

See error:

sq() returns a float:
https://processing.org/reference/sq_.html

Try:
total*total which returns an int

Or this to convert the float to an int:
https://processing.org/reference/intconvert_.html

The i -- seemed to work once I corrected code but really should be i-- without spaces.

Consider this:

int t, total;
float itemSize;

void setup() 
  {
  size(800, 800); 
  //pixelDensity(2);
  smooth();
  rectMode(CENTER);

  total = 4;
  t = 4;
  itemSize = width/total;
  }

void draw() 
  {
  for (int i = 0; i < sq(total); i ++) 
    {
    float x = i % total * itemSize + itemSize/2;
    float y = i / total * itemSize + itemSize/2;
    fill(-1);
    square(x, y, itemSize * 0.8);

    textAlign(CENTER, CENTER);
    textSize(24);

    fill(0);
    text((i/t)%2, x, y-60);
    text(i%t, x, y-30);
    text(i, x, y);
    text(i/t, x, y+30);
    text(t-i%t, x, y+60); 
    }
  }

Output from above:

From the above I was able to do some math and achieve this:

An if\else statement was used to determine odd\even lines and print the correct order.

I took advantage of integer math in my example above.

:)

The problem seems to me that you are using the index i to determine both the value to display and the position to display it. Since you want to change the order the numbers are displayed there is no simple formulae linking the value to position, you need a more elaborate algorithm.
If we number the rows and columns in the initial state we have
g1

The display position of any cell is determined using c and r.

To calculate the value to be displayed I will introduce 2 new variables c1 and r1 as it will simplify the problem later. I also introduce a new variable gs which is the grid square size, in this example, 4

So in the initial state we calculate the value to be stored with
c1 = c; r1 = r; v = 1 + c1 + r1 * gs;

Now if we look at the other 3 grids

The first is flipped horizontally so use
c1 = gs - c - 1; r1 = r; v = 1 + c1 + r1 * gs;

the second is flipped vertically so use
c1 = c; r1 = gs - r - 1; v = 1 + c1 + r1 * gs;

and the final one flipped in both directions so use
c1 = gs - c - 1; r1 = gs - r - 1; v = 1 + c1 + r1 * gs;

So use a double loop like this replacing the ??? depending on which grid you are using.

  for (int r = 0; r < grid_size; r++) {
    int r1 = ?????;
    for (int c = 0; c < grid_size; c++) {
      int c1 =?????;
      int v = 1 + c1 + r1 * grid_size;
      float x = (c + 0.5) * itemSize;
      float y = (r + 0.5) * itemSize;
      fill(-1);
      square(x, y, itemSize * 0.8);
      fill(0);
      textSize(40);
      text(v, x, y);
    }
  }

I have tested this and it works fine.

2 Likes

Amazing! Thank you very much, I can come up with an answer along your lines, but understanding it is still a bit difficult for me, I will study and learn it carefully.

Your reply helped me a lot and I wish you all the best :slight_smile:

Thank you for your reply, maybe I’m not competent enough, I wasn’t able to achieve the results as you did, I’ll keep working on it, thanks!

A simple package is carried out on your basis, so that four arrangements can be quickly formed.
Thank you for the algorithm provided!

int total;
float itemSize;

void setup() {
  size(800, 800); 
  pixelDensity(2);
  smooth();
  rectMode(CENTER);

  total = 4;
  itemSize = width/total;
}

void draw() {
  clear();
  drawGrid("lt");
}


// lt -> left top
// rt -> right top
// ld -> left down
// rd -> right down
void drawGrid(String str) {
  int r1 = 0;
  int c1 = 0;
  for (int r = 0; r < total; r++) {
    if (str == "lt" || str == "rt") {
      r1 = r;
    } else if (str == "ld" || str == "rd") {
      r1 = total - r - 1;
    }

    for (int c = 0; c < total; c++) {
      if (str == "lt" || str == "ld") {
        c1 = c;
      } else if (str == "rt" || str == "rd") {
        c1 = total-c-1;
      }
      int v = 1 + c1 + r1 * total;
      float x = (c + 0.5) * itemSize;
      float y = (r + 0.5) * itemSize;
      fill(-1);
      square(x, y, itemSize * 0.8);
      fill(0);
      textSize(40);
      text(v, x, y);
    }
  }
}

algorithm by: @quark For loop matrix index - #3 by quark

In Java strings should not be compared with the == operator, instead you should use the equals() method so
str == "ld"
becomes
str.equals("id")
I will leave you to google it for an explanation.

Apart from that congratulations on a nice implementation.

1 Like

Just to avoid any possible confusion to others, you might wish to edit the two comments just preceding drawGrid(…): ‘lb’ and ‘rb’ should be ‘ld’ and ‘rd’ respectively. Your code is correct (apart from the use of == for string comparison mentioned by @quark )

Phil.

Okay, thanks for the reminder. It has been modified.

1 Like

Learned something new again, many thanks :slight_smile:
Processing String_equals

String a = new String("abc");
String b = new String("abc");

println(b.equals(a));
// retuen true
println(a == b);
// retuen false

I have adjusted the code:

int total;
float itemSize;

void setup() {
  size(800, 800); 
  pixelDensity(2);
  smooth();
  rectMode(CENTER);
  textAlign(CENTER, CENTER);
  textSize(60);
  total = 4;
  itemSize = width/total;
}

void draw() {
  clear();
  //drawGrid("lt");
  //drawGrid("rt");
  //drawGrid("ld");
  drawGrid("rd");
}


// lt -> left top
// rt -> right top
// ld -> left down
// rd -> right down
void drawGrid(String str) {
  int r1 = 0;
  int c1 = 0;
  for (int r = 0; r < total; r++) {
    if (str.equals("lt") || str.equals("rt")) {
      r1 = r;
    } else if (str.equals("ld")|| str.equals("rd")) {
      r1 = total - r - 1;
    }

    for (int c = 0; c < total; c++) {
      if (str.equals("lt")|| str.equals("ld")) {
        c1 = c;
      } else if (str.equals("rt")|| str.equals("rd")) {
        c1 = total-c-1;
      }
      int v = 1 + c1 + r1 * total;
      float x = (c + 0.5) * itemSize;
      float y = (r + 0.5) * itemSize;
      fill(-1);
      square(x, y, itemSize * 0.8);
      fill(0);
      text(v, x, y);
    }
  }
}

Hello @niuuin,

Some suggestions:

  • use if statements to determine a “choice” outside of the loop.
    This is done once.

  • use switch\case statements inside the loop.
    Once choice is made for each step through the loop.

Example

 int choice; 

//if statements set choice

  for (int r = 0; r < total; r++) 
    {
    for (int c = 0; c < total; c++) 
      {
      choice = 0;
       switch(choice) {
      case 0: 
        r1 = r;
        c1 = c;
        break;
      case 1: 
        r1 = r;
        c1 = total-c-1;
        break;
      case 2: 
      // ???
        break;
      case 3: 
      // ?;
        break;  
      default:
        r1 = r;
        c1 = c;
        break;
        }
    // code
     } 

References:

Look up the reference for clear():
https://processing.org/reference/clear_.html
That will make things clear!

Consider this at start of draw():
https://www.processing.org/reference/background_.html

:)

1 Like

I would not recommend the use of a switch statement inside the inner loop although it does make sense to keep the string comparisons outside the loop. The drawGrid method below shows how to do this elegantly and efficiently.

// lt -> left top
// rt -> right top
// ld -> left down
// rd -> right down
// Any other value will be treaed as lt
void drawGrid(String str) {
  int r1 = 0;
  int c1 = 0;
  boolean flipY = str.equals("ld") || str.equals("rd");
  boolean flipX = str.equals("rt") || str.equals("rd");
  for (int r = 0; r < total; r++) {
    r1 = flipY ? total - r - 1 : r;
    for (int c = 0; c < total; c++) {
      c1 = flipX ? total-c-1 : c;
      int v = 1 + c1 + r1 * total;
      float x = (c + 0.5) * itemSize;
      float y = (r + 0.5) * itemSize;
      fill(-1);
      square(x, y, itemSize * 0.8);
      fill(0);
      text(v, x, y);
    }
  }
}

Note I use the ternary operator statements inside the loop like this

c1 = flipX ? total-c-1 : c;
// variable = boolean-condition ? value-if-true : value-if-false;

the ternary statement returns a value based on whether a condition is true so if flipX is true then c1=total-c-1 but if false then c1=c

3 Likes

your explanation is great and easy to understand

1 Like

Hello,

The Processing Wiki has some troubleshooting tips including this one:
https://github.com/processing/processing/wiki/Troubleshooting

Another good resource:

:)

Thank you very much, I will read it carefully. :slight_smile:

1 Like