Adding elements outward in a circle

edited May 2017 in How To...

Hello, I'm quite new to Processing. I know how to use for loops to add elements, but I don't know how to go about creating an element, which expand from a center.

Answers

  • edited May 2017

    You can post your example image here. I cannot see it without signing up for a Dropbox account.

  • Ah, sorry. Here it is.

  • @kasperrubin -- re:

    creating an element, which expand from a center

    What, precisely, are you trying to do?

    • Add a hex "0" and then add a single object which is all of the hexes "1" joined into one shape?
    • Add "0", then add every separate element "1", in no certain order?
    • Add "0", then add each element "1" in some particular order (clockwise starting from the top, or whatever)?

    For a related discussion, see: https://forum.processing.org/two/discussion/comment/75708/#Comment_75708

  • That does seem like a possible solution. The question is what do I truly want with my grid, other than making it work with a sound input? I don't know. Maybe tomorrow I will.

    But thanks for your help. I will write again when I understand this a little better :)

  • If you are trying to do simple radial sound visualizations that are nested like rings, then instead of a grid consider simply:

    1. drawing centered shapes of different sizes (like rectangles and ellipses), or
    2. translating to the center of the screen and using scale() to draw the same thing at different sizes.
  • Okay, I found out what I want with the shapes. I need some way of adding copies of 1 hexagon in random order, as long as the next shape is adjacent to one of the already created shapes.

    Like this:

  • edited May 2017

    Are you adding them one at a time, or are they growing in many places at once?

    Does it matter if the space where you were going to add a new hexagon is already filled with a hexagon -- do you need to check if it is empty first?

  • Actually they will be growing from up to three different places at once. The idea is that they will be formed by trebble, midrange and bass frequencies, starting from one center and growing outwards, while still appearing like one structure, other than three arms.

    I'm not sure I understand what you mean. If there is already a hexagon, it will place it on top of that?

    But yes, I think it matters. Because a user is going to be able to decide how many elements the figure will consist of and if it's drawing new elements on top of already existing ones, how will you know if the numbers are right?

  • Forget about growing it for now. Can you just draw a bunch of hexagons in a grid that covers the entire sketch (with the center one being in the center). That would be a great start...

  • edited May 2017

    I can.

    float[] hexagonX = new float[width];
    float[] hexagonY = new float[height];
    float scaleF;
    
    void setup() {
      size(1000, 700);
      background(0);
      stroke(255);
      smooth();
      noLoop();
    }
    
    void draw() { 
    //scale factor to determine the size of the grid
    scaleF = 1.5;
      //loop for drawing an hexagon grid
      for (int i = 0; i < hexagonX.length; i ++) {   
        for (int j = 0; j < hexagonY.length; j++) {
          if (j % 2 == 0) {
            hexagonX[i] = scaleF * (i * 102);    
          } else if (j % 2 != 0) {
            hexagonX[i] = scaleF * (51 + i * 102);
          }
          hexagonY[j] = scaleF * (j * 28);
          //draws every hexagon
          hexagon(int(hexagonX[i]), int(hexagonY[j]));
        }
      }
    }
    
    //function to make one hexagon
      void hexagon(int x, int y) {
      pushMatrix();
      translate(x, y);
      scale(scaleF);
      line(-17, -28, 17, -28); // upper horizontal line
      line(-34, 0, -17, -28); // left upper line
      line(-34, 0, -17, 28); // left lower line
      line(-17, 28, 17, 28); //lower horizontal line
      line(17, 28, 34, 0);  // right lower line
      line(34, 0, 17, -28); //right upper line
      popMatrix();
    }
    
  • Please edit your post (gear icon in the top right corner of your post), select your code and hit ctrl+o to format your code. Make sure there is an empty line above and below your code.

    This problem consist of mapping all hexagon's centers in he sketch area. Then you randomly place an hexagon applying two conditions to the next placement:

    1. Make sure the next placement is an empty spot.
    2. Make sure you have at least one hexagon as a neighbor

    This condition doesn't apply to the first placement.

    Kf

  • This is not how the code formatter should look like, but it's the closest I could get. I tried putting an empty line above and below, but then it wouldn't format anything at all.

    So to make random hexagons map out from a centered element, all I need to do is add an if else statement. How do I write those conditions?

  • (code formatted)

    One obvious thing

    If (thing == value)
      Do something
    Else If (thing != value)
      Do something else
    

    The second condition there is unnecessary - the else is already the opposite of the if, no need for another check

    If (thing == value)
      Do something
    Else
      Do something else
    

    This is enough.

  • Also width and height are both 0 in lines 1 and 2 because they only get set after setup has run.

    Does your code run? The above suggests you either see nothing or will get an array index out of bounds exception

  • Whoa there, hold on. Back up and slow down. You are drawing hexagons, yes, but not in a way that is at all useful. You want a grid of hexagons, right? If you think about it, a grid of hexagons is still a plain old 2D grid of rectangles - it's just that the even numbered columns are shifted down a bit. So let's back up even more and start with a grid of rectangles:

    class Rectangle {
      float x;
      float y;
      color c;
      Rectangle(float ix, float iy) {
        x = ix;
        y = iy;
        c = color(random(255), random(255), random(255));
      }
      void draw() {
        fill(c);
        noStroke();
        rect(x, y, rx, ry);
      }
    }
    
    Rectangle[][] rects;
    
    float rx = 100;
    float ry = 70;
    int wide;
    int tall;
    
    void setup() {
      size(1000, 700);
      wide = int(width/rx);
      tall = int(height/ry);
      rects = new Rectangle[wide][tall];
      for (int y = 0; y < wide; y++) {
        for (int x = 0; x < tall; x++) {
          rects[x][y] = new Rectangle(x*rx, y*ry);
        }
      }
    }
    
    void draw() {
      background(0);
      for (int y = 0; y < wide; y++) {
        for (int x = 0; x < tall; x++) {
          rects[x][y].draw();
        }
      }
    }
    
  • Now, let's shift the even columns down half way:

    class Rectangle {
      float x;
      float y;
      color c;
      Rectangle(float ix, float iy) {
        x = ix;
        y = iy;
        c = color(random(255), random(255), random(255));
      }
      void draw() {
        fill(c);
        noStroke();
        rect(x, y, rx, ry);
      }
    }
    
    Rectangle[][] rects;
    
    float rx = 100;
    float ry = 70;
    int wide;
    int tall;
    
    void setup() {
      size(1000, 700);
      wide = int(width/rx);
      tall = int(height/ry);
      rects = new Rectangle[wide][tall];
      for (int y = 0; y < wide; y++) {
        for (int x = 0; x < tall; x++) {
          if ( x % 2 == 0) {
            rects[x][y] = new Rectangle(x*rx, y*ry);
          } else {
            rects[x][y] = new Rectangle(x*rx, (y+.5)*ry);
          }
        }
      }
    }
    
    void draw() {
      background(0);
      for (int y = 0; y < wide; y++) {
        for (int x = 0; x < tall; x++) {
          rects[x][y].draw();
        }
      }
    }
    

    Alright. Looks hexagon-y already!

  • In fact, it looks so hexagon-grid-like already, why don't we just try drawing hexagons now?!?

    class Rectangle {
      float x;
      float y;
      color c;
      Rectangle(float ix, float iy) {
        x = ix;
        y = iy;
        c = color(random(255), random(255), random(255));
      }
      void draw_rect() {
        fill(c);
        noStroke();
        rect(x, y, rx, ry);
      }
    
      void draw() {
        noFill();
        stroke(c);
        pushMatrix();
        translate(x, y);
        line(-17, -28, 17, -28);
        line(-34, 0, -17, -28);
        line(-34, 0, -17, 28);
        line(-17, 28, 17, 28);
        line(17, 28, 34, 0);
        line(34, 0, 17, -28);
        popMatrix();
      }
    }
    
    Rectangle[][] rects;
    
    float rx = 100;
    float ry = 70;
    int wide;
    int tall;
    
    void setup() {
      size(1000, 700);
      wide = int(width/rx);
      tall = int(height/ry);
      rects = new Rectangle[wide][tall];
      for (int y = 0; y < wide; y++) {
        for (int x = 0; x < tall; x++) {
          if ( x % 2 == 0) {
            rects[x][y] = new Rectangle(x*rx, y*ry);
          } else {
            rects[x][y] = new Rectangle(x*rx, (y+.5)*ry);
          }
        }
      }
    }
    
    void draw() {
      background(0);
      for (int y = 0; y < wide; y++) {
        for (int x = 0; x < tall; x++) {
          rects[x][y].draw();
        }
      }
    }
    

    Hey - not bad!

  • edited May 2017

    Let's adjust the spacing now, back to what your grid had. Let's also fix the bug my previous posts had where I had wide and tall swapped as the bounds for my for loop (Whoops! Test your code better, TF!):

    class Rectangle {
      float x;
      float y;
      color c;
      Rectangle(float ix, float iy) {
        x = ix;
        y = iy;
        c = color(random(255), random(255), random(255));
      }
      void draw() {
        noFill();
        stroke(c);
        pushMatrix();
        translate(x, y);
        line(-17, -28, 17, -28);
        line(-34, 0, -17, -28);
        line(-34, 0, -17, 28);
        line(-17, 28, 17, 28);
        line(17, 28, 34, 0);
        line(34, 0, 17, -28);
        popMatrix();
      }
    }
    
    Rectangle[][] rects;
    
    float rx = 51;
    float ry = 56;
    int wide;
    int tall;
    
    void setup() {
      size(1000, 700);
      wide = int(width/rx);
      tall = int(height/ry);
      println(wide + " " + tall );
      rects = new Rectangle[wide][tall];
      for (int y = 0; y < tall; y++) {
        for (int x = 0; x < wide; x++) {
          if ( x % 2 == 0) {
            rects[x][y] = new Rectangle(x*rx, y*ry);
          } else {
            rects[x][y] = new Rectangle(x*rx, (y+.5)*ry);
          }
        }
      }
    }
    
    void draw() {
      background(0);
      for (int y = 0; y < tall; y++) {
        for (int x = 0; x < wide; x++) {
          rects[x][y].draw();
        }
      }
    }
    

    This is where I wanted to make sure you were STARTING from. This is what I had in mind when I asked you if you could just draw a grid of hexagons.

  • A few more minor changes now. For one, they are Hexagons, so let's rename things a bit. We're going to shift the even columns up instead of down now, and we've meddled with the limits for how many hexagons wide and tall we're going to do.

    Oh, and each hexagon can now be active, and we try to activate the middle one when we do a mouse click - try it!

    class Hexagon {
      float x;
      float y;
      color c;
      boolean active;
      Hexagon(float ix, float iy) {
        x = ix;
        y = iy;
        active = false;
        c = color(random(255), random(255), random(255));
      }
      void draw() {
        if(active){
          fill(c);
        } else {
          noFill();
        }
        stroke(255);
        pushMatrix();
        translate(x, y);    
        line(-17, -28, 17, -28);
        line(-34, 0, -17, -28);
        line(-34, 0, -17, 28);
        line(-17, 28, 17, 28);
        line(17, 28, 34, 0);
        line(34, 0, 17, -28);
        popMatrix();
      }
    }
    
    Hexagon[][] hexagons;
    
    float rx = 51;
    float ry = 56;
    int wide;
    int tall;
    
    int active_counter = 0;
    int max_hexagons;
    
    void setup() {
      size(1000, 700);
      wide = int(width/rx) + 1;
      tall = int(height/ry) + 2;
      max_hexagons = tall * wide;
      println(wide + " " + tall );
      hexagons = new Hexagon[wide][tall];
      for (int y = 0; y < tall; y++) {
        for (int x = 0; x < wide; x++) {
          if ( x % 2 == 0) {
            hexagons[x][y] = new Hexagon(x*rx, y*ry);
          } else {
            hexagons[x][y] = new Hexagon(x*rx, (y-.5)*ry);
          }
        }
      }
    }
    
    void draw() {
      background(0);
      for (int y = 0; y < tall; y++) {
        for (int x = 0; x < wide; x++) {
          hexagons[x][y].draw();
        }
      }
    }
    
    void mousePressed(){
      if(active_counter == 0){
        hexagons[int(wide/2)][int(tall/2)].active = true;
        active_counter++;
      }
    }
    

    Software development is a process of making small changes and making sure they work. Did you try to click like I suggested? Were you totally underwhelmed when the middle hexagon DIDN'T light up? Can you SPOT THE BUG???


  • No seriously, this is a good one. Why doesn't the hexagon light up?

    Last chance to try to work it out yourself.

    Answer in next post...

  • AH HA!

    class Hexagon {
      float x;
      float y;
      color c;
      boolean active;
      Hexagon(float ix, float iy) {
        x = ix;
        y = iy;
        active = false;
        c = color(random(255), random(255), random(255));
      }
      void draw() {
        if(active){
          fill(c);
        } else {
          noFill();
        }
        stroke(255);
        pushMatrix();
        translate(x, y);
        beginShape();
        vertex(-17, -28);
        vertex(17, -28);
        vertex(34,0);
        vertex(17,28);
        vertex(-17,28);
        vertex(-34,0);
        endShape(CLOSE);    
        popMatrix();
      }
    }
    
    Hexagon[][] hexagons;
    
    float rx = 51;
    float ry = 56;
    int wide;
    int tall;
    
    int active_counter = 0;
    int max_hexagons;
    
    void setup() {
      size(1000, 700);
      wide = int(width/rx) + 1;
      tall = int(height/ry) + 2;
      max_hexagons = tall * wide;
      println(wide + " " + tall );
      hexagons = new Hexagon[wide][tall];
      for (int y = 0; y < tall; y++) {
        for (int x = 0; x < wide; x++) {
          if ( x % 2 == 0) {
            hexagons[x][y] = new Hexagon(x*rx, y*ry);
          } else {
            hexagons[x][y] = new Hexagon(x*rx, (y-.5)*ry);
          }
        }
      }
    }
    
    void draw() {
      background(0);
      for (int y = 0; y < tall; y++) {
        for (int x = 0; x < wide; x++) {
          hexagons[x][y].draw();
        }
      }
    }
    
    void mousePressed(){
      if(active_counter == 0){
        hexagons[int(wide/2)][int(tall/2)].active = true;
        active_counter++;
      }
    }
    

    You don't get any fill when you only draw lines!

  • And now that we have the central hexagon lighting up, and we know which one it is, so we know its position, we might consider drawing things so that that specific hexagon is ACTUALLY in the center of the sketch:

    class Hexagon {
      float x;
      float y;
      color c;
      boolean active;
      Hexagon(float ix, float iy) {
        x = ix;
        y = iy;
        active = false;
        c = color(random(255), random(255), random(255));
      }
      void draw() {
        if(active){
          fill(c);
        } else {
          noFill();
        }
        stroke(255);
        pushMatrix();
        translate(x, y);
        beginShape();
        vertex(-17, -28);
        vertex(17, -28);
        vertex(34,0);
        vertex(17,28);
        vertex(-17,28);
        vertex(-34,0);
        endShape(CLOSE);    
        popMatrix();
      }
    }
    
    Hexagon[][] hexagons;
    
    float rx = 51;
    float ry = 56;
    int wide;
    int tall;
    
    int active_counter = 0;
    int max_hexagons;
    
    float Xoffset, Yoffset;
    
    void setup() {
      size(1000, 700);
      wide = int(width/rx) + 2;
      tall = int(height/ry) + 2;
      max_hexagons = tall * wide;
      println(wide + " " + tall );
      hexagons = new Hexagon[wide][tall];
      for (int y = 0; y < tall; y++) {
        for (int x = 0; x < wide; x++) {
          if ( x % 2 == 0) {
            hexagons[x][y] = new Hexagon(x*rx, y*ry);
          } else {
            hexagons[x][y] = new Hexagon(x*rx, (y-.5)*ry);
          }
        }
      }
      float targetX = width/2;
      float targetY = height/2;
      Xoffset = hexagons[int(wide/2)][int(tall/2)].x - targetX;
      Yoffset = hexagons[int(wide/2)][int(tall/2)].y - targetY;
    }
    
    void draw() {
      background(0);
      translate(-Xoffset,-Yoffset);
      for (int y = 0; y < tall; y++) {
        for (int x = 0; x < wide; x++) {
          hexagons[x][y].draw();
        }
      }
    }
    
    void mousePressed(){
      if(active_counter == 0){
        hexagons[int(wide/2)][int(tall/2)].active = true;
        active_counter++;
      }
    }
    

    Also note the change to the wide variable now as well - we might need an extra column to fully cover the grid.

    Dang, that is a sweet honeycomb! Take that, bees!

  • Can we activate them at random? Yep! But the bottom row wouldn't light up - turns out we might actually need a +3 on the tall! Here's random lighting up:

    class Hexagon {
      float x;
      float y;
      color c;
      boolean active;
      Hexagon(float ix, float iy) {
        x = ix;
        y = iy;
        active = false;
        c = color(random(255), random(255), random(255));
      }
      void draw() {
        if(active){
          fill(c);
        } else {
          noFill();
        }
        stroke(255);
        pushMatrix();
        translate(x, y);
        beginShape();
        vertex(-17, -28);
        vertex(17, -28);
        vertex(34,0);
        vertex(17,28);
        vertex(-17,28);
        vertex(-34,0);
        endShape(CLOSE);    
        popMatrix();
      }
    }
    
    Hexagon[][] hexagons;
    
    float rx = 51;
    float ry = 56;
    int wide;
    int tall;
    
    int active_counter = 0;
    int max_hexagons;
    
    float Xoffset, Yoffset;
    
    void setup() {
      size(1000, 700);
      wide = int(width/rx) + 2;
      tall = int(height/ry) + 3;
      max_hexagons = tall * wide;
      println(wide + " " + tall );
      hexagons = new Hexagon[wide][tall];
      for (int y = 0; y < tall; y++) {
        for (int x = 0; x < wide; x++) {
          if ( x % 2 == 0) {
            hexagons[x][y] = new Hexagon(x*rx, y*ry);
          } else {
            hexagons[x][y] = new Hexagon(x*rx, (y-.5)*ry);
          }
        }
      }
      float targetX = width/2;
      float targetY = height/2;
      Xoffset = hexagons[int(wide/2)][int(tall/2)].x - targetX;
      Yoffset = hexagons[int(wide/2)][int(tall/2)].y - targetY;
    }
    
    void draw() {
      background(0);
      translate(-Xoffset,-Yoffset);
      for (int y = 0; y < tall; y++) {
        for (int x = 0; x < wide; x++) {
          hexagons[x][y].draw();
        }
      }
        int rand_X = int(random(wide));
        int rand_Y = int(random(tall));
        hexagons[rand_X][rand_Y].active = true;
        active_counter++;
    }
    
    void mousePressed(){
      if(active_counter == 0){
        hexagons[int(wide/2)][int(tall/2)].active = true;
        active_counter++;
      } else if(active_counter < max_hexagons) {
        int rand_X = int(random(wide));
        int rand_Y = int(random(tall));
        hexagons[rand_X][rand_Y].active = true;
        active_counter++;
      } 
    }
    

    Clicking also does it.

  • Answer ✓

    And with a little more effort, each frame a random hexagon is looked for until an active one is found. Then a random direction away from that hexagon is picked and that adjacent hexagon also activates. Due to randomness, this might take a while for the active area to expand, so it's going to happen automatically now in draw:

    class Hexagon {
      float x;
      float y;
      color c;
      boolean active;
      Hexagon(float ix, float iy) {
        x = ix;
        y = iy;
        active = false;
        c = color(random(255), random(255), random(255));
      }
      void draw() {
        if (active) {
          fill(c);
        } else {
          noFill();
        }
        stroke(255);
        pushMatrix();
        translate(x, y);
        beginShape();
        vertex(-17, -28);
        vertex(17, -28);
        vertex(34, 0);
        vertex(17, 28);
        vertex(-17, 28);
        vertex(-34, 0);
        endShape(CLOSE);    
        popMatrix();
      }
    }
    
    Hexagon[][] hexagons;
    
    float rx = 51;
    float ry = 56;
    int wide;
    int tall;
    
    int active_counter = 0;
    int max_hexagons;
    
    float Xoffset, Yoffset;
    
    void setup() {
      size(1000, 700);
      wide = int(width/rx) + 2;
      tall = int(height/ry) + 3;
      max_hexagons = tall * wide;
      println(wide + " " + tall );
      hexagons = new Hexagon[wide][tall];
      for (int y = 0; y < tall; y++) {
        for (int x = 0; x < wide; x++) {
          if ( x % 2 == 0) {
            hexagons[x][y] = new Hexagon(x*rx, y*ry);
          } else {
            hexagons[x][y] = new Hexagon(x*rx, (y-.5)*ry);
          }
        }
      }
      float targetX = width/2;
      float targetY = height/2;
      Xoffset = hexagons[int(wide/2)][int(tall/2)].x - targetX;
      Yoffset = hexagons[int(wide/2)][int(tall/2)].y - targetY;
    }
    
    void draw() {
      background(0);
      translate(-Xoffset, -Yoffset);
      for (int y = 0; y < tall; y++) {
        for (int x = 0; x < wide; x++) {
          hexagons[x][y].draw();
        }
      }
      if(active_counter > 0 && active_counter < max_hexagons){
        nextHex();
      }
    }
    
    int[] stepX = { -1, -1, 0, 0, 1, 1 };
    int[][] stepY = {{ 0, 1, -1, 1, 0, 1 }, { 0, -1, -1, 1, 0, -1 } };
    
    void mousePressed() {
      if (active_counter == 0) {
        hexagons[int(wide/2)][int(tall/2)].active = true;
        active_counter++;
      }
    //  else if (active_counter < max_hexagons) {
    //    nextHex();
    //  }
    }
    
    void nextHex() {
      int rand_X = int(random(wide));
      int rand_Y = int(random(tall));
      while (!hexagons[rand_X][rand_Y].active) {
        rand_X = int(random(wide));
        rand_Y = int(random(tall));
      }
      int rand_D = int(random(6));
      if (
        rand_X+stepX[rand_D] >= 0 && 
        rand_X+stepX[rand_D] < wide &&
        rand_Y+stepY[rand_Y%2][rand_D] >= 0 && 
        rand_Y+stepY[rand_Y%2][rand_D] < tall
        ) {
        if (!hexagons[rand_X+stepX[rand_D]][rand_Y+stepY[rand_Y%2][rand_D]].active) {
          active_counter++;
        }
        hexagons[rand_X+stepX[rand_D]][rand_Y+stepY[rand_Y%2][rand_D]].active = true;
        // Debug line.
        //line(hexagons[rand_X][rand_Y].x,hexagons[rand_X][rand_Y].y,hexagons[rand_X+stepX[rand_D]][rand_Y+stepY[rand_Y%2][rand_D]].x, hexagons[rand_X+stepX[rand_D]][rand_Y+stepY[rand_Y%2][rand_D]].y); 
      }
    }
    

    So now you have hexagons spreading out from a central point. You can fiddle with this a bit more yourself to have it activate based on music or whatever. Send beer money via paypal to tfguy44 at gmail dot com (so thirsty!).

  • edited May 2017

    So, uh, yeah... the spreading is a little wrong. Fixes:

    int[][] stepY = {{ 0, 1, -1, 1, 0, 1 }, { 0, -1, -1,1, 0, -1 } };
    

    And:

      if (
        rand_X+stepX[rand_D] >= 0 && 
        rand_X+stepX[rand_D] < wide &&
        rand_Y+stepY[rand_X%2][rand_D] >= 0 && 
        rand_Y+stepY[rand_X%2][rand_D] < tall
        ) {
        if (!hexagons[rand_X+stepX[rand_D]][rand_Y+stepY[rand_X%2][rand_D]].active) {
    

    And also:

    hexagons[rand_X+stepX[rand_D]][rand_Y+stepY[rand_X%2][rand_D]].active = true;
    

    Basically anywhere I was checking rand_Y%2 should be rand_X%2....

  • edited May 2017

    @TfGuy44 Thank you so much for explaining this is such humorous detail and steps!

    There is quite a number of things I will need to read up upon, but perhaps you could enlighten me on this one: What does it do?

    int[] stepX = { -1, -1, 0, 0, 1, 1 };
    int[][] stepY = {{ 0, 1, -1, 1, 0, 1 }, { 0, -1, -1,1, 0, -1 } };
    
  • A hexagon has six hexagons that surround it. If you give each hexagon a row number and a column number, how do you have to change the row and column number of a given hexagons to get to those other six surrounding hexagons' row and column numbers? The two above and below are easy: -1 and 1 in the column number, no change in the row number. The four in other columns are a little trickier: you change the column number by -1 or 1, but you might either stay in the same row (0) or move up a row (-1) or down a row(1), depending on if you're dealing with a hexagon in an even numbered column or not.

    Here on the forum, to post code properly, select the code in your post and hit Ctrl + o.

  • Still a little hard to comprehend :) I'm going to rewrite your example and see what everything means.

  • edited May 2017

    Okay, so I did some modifications and it kinda works alright now.

    So I thought I would replace the created hexagons with an SVG hexagon, to get some more detail into the shape. That though is causing some issues.

    Inside my projects folder I have a folder called Data and the "hexagon-three-sides.svg" is placed there.

    PShape hexagonSVG;
    
    Hexagon[] [] hexagons;
    
    float rx = 51;
    float ry = 56;
    int wide;
    int tall;
    
    int active_counter = 0;
    int max_hexagons;
    
    float Xoffset, Yoffset;
    
    int[] stepX = { -1, -1, 0, 0, 1, 1 };
    int[][] stepY = {{ 0, 1, -1, 1, 0, 1 }, { 0, -1, -1, 1, 0, -1 } };
    
    class Hexagon {
      float x;
      float y;
      int rand;
      color[] colors;
      boolean active;
    
    
      Hexagon (float ix, float iy) {
        x = ix;
        y = iy;
        active = false;
    
        // Array of colors
        colors = new color[10];
        colors[0] = color(#62563D); // Infantry green
        colors[1] = color(#2C2B2D); // Parisian night blue
        colors[2] = color(#3E2224); // Purple heart
        colors[3] = color(#A49F9B); // Wild dove grey
        colors[4] = color(#684F40); // Brown
        colors[5] = color(#5C573D); // Moss green
        colors[6] = color(#B9897F); // Pink
        colors[7] = color(#24283B); // Dark blue
        colors[8] = color(#1F1D20); // Black
        colors[9] = color(#C5A9A2); // Brazilian clay
    
        // Takes the colors array and output random colors
        rand = (int)random(colors.length);
      }
      void draw() {
        if (active) {
    
          // Call the colors array in random order
          fill(colors[rand]);
        } else {
          noFill();
        }
    
        stroke(80);
        pushMatrix();
        translate(x, y);
        shape(hexagonSVG, 100, 100, 100, 100);
        popMatrix();
      }
    }
    
    void setup() {
      size(1000, 700);
      hexagonSVG = loadShape("hexagon-three-sides.svg");
    
      wide = int(width/rx) + 2;
    
      tall = int (height/ry) + 2;
    
      max_hexagons = 40;
    
      hexagons = new Hexagon [wide] [tall];
    
      for (int y = 0; y < tall; y++) {
        for (int x = 0; x < wide; x++) {
    
          if ( x % 2 == 0) {
    
            hexagons[x] [y] = new Hexagon(x*rx, y*ry);
    
          } else {
    
            hexagons[x] [y] = new Hexagon(x*rx, (y-.5)*ry);
          }
        }
      }
    
      float targetX = width/2;
      float targetY = height/2;
    
      Xoffset = hexagons [int(wide/2)] [int(tall/2)] .x - targetX;
      Yoffset = hexagons [int(wide/2)] [int(tall/2)] .y - targetY;
    }
    
    void draw () {
      background(0);
      translate(-Xoffset, -Yoffset);
      for (int y = 0; y < tall; y++) {
        for (int x = 0; x < wide; x++) {
    
          hexagons[x] [y] .draw();
        }
      }
      if (active_counter > 0 && active_counter < max_hexagons) {
        nextHex();
      }
    }
    
    void mousePressed() {
    
      if (active_counter == 0) {
    
        hexagons[int(wide/2)][int(tall/2)].active = true;
    
        active_counter++;
      }
    }
    
    void nextHex() {
      int randX = int(random(wide));
      int randY = int(random(tall));
      while (!hexagons[randX][randY] .active) {
        randX = int(random(wide));
        randY = int(random(tall));
      } 
      int randD = int(random(6));
      if (
        randX + stepX[randD] >= 0 && 
        randX + stepX[randD] < wide &&
        randY + stepY[randX % 2][randD] >= 0 && 
        randY + stepY[randX % 2][randD] < tall
        ) {
        if (!hexagons[randX + stepX[randD]][randY + stepY[randX % 2][randD]] .active) {
          active_counter++;
        }
        hexagons[randX + stepX[randD]][randY + stepY[randX % 2][randD]] .active = true;
      }
    }
    

    I'm also getting a lengthy error concerning the PShape:

    java.lang.ArrayIndexOutOfBoundsException: 1
        at processing.core.PShapeSVG.parsePoly(PShapeSVG.java:461)
        at processing.core.PShapeSVG.parseChild(PShapeSVG.java:335)
        at processing.core.PShapeSVG.parseChildren(PShapeSVG.java:289)
        at processing.core.PShapeSVG.<init>(PShapeSVG.java:209)
        at processing.awt.PShapeJava2D.<init>(PShapeJava2D.java:57)
        at processing.awt.PShapeJava2D.createShape(PShapeJava2D.java:80)
        at processing.core.PShapeSVG.parseChild(PShapeSVG.java:310)
        at processing.core.PShapeSVG.parseChildren(PShapeSVG.java:289)
        at processing.core.PShapeSVG.<init>(PShapeSVG.java:209)
        at processing.awt.PShapeJava2D.<init>(PShapeJava2D.java:57)
        at processing.awt.PShapeJava2D.createShape(PShapeJava2D.java:80)
        at processing.core.PShapeSVG.parseChild(PShapeSVG.java:310)
        at processing.core.PShapeSVG.parseChildren(PShapeSVG.java:289)
        at processing.core.PShapeSVG.<init>(PShapeSVG.java:209)
        at processing.core.PShapeSVG.<init>(PShapeSVG.java:116)
        at processing.awt.PShapeJava2D.<init>(PShapeJava2D.java:52)
        at processing.awt.PGraphicsJava2D.loadShape(PGraphicsJava2D.java:1839)
        at processing.core.PGraphics.loadShape(PGraphics.java:1741)
        at processing.core.PApplet.loadShape(PApplet.java:11450)
        at Replicating_polygons.setup(Replicating_polygons.java:108)
        at processing.core.PApplet.handleDraw(PApplet.java:2414)
        at processing.awt.PSurfaceAWT$12.callDraw(PSurfaceAWT.java:1547)
        at processing.core.PSurfaceNone$AnimationThread.run(PSurfaceNone.java:316)
    
  • Can you just draw the hexagon SVG shape without the rest of the sketch? That is:

    void setup(){
      size(400,400);
      PShape hexagonSVG = loadShape("hexagon-three-sides.svg");
      background(0);
      translate(200,200);
      shape( hexagonSVG,100,100,100,100 );
      noLoop();
    }
    
    void draw(){}
    
  • edited May 2017

    You know, scrap that SVG for now. It's not absolutely necessary for my project.

    As of now the hexagon structure is build automatically in a random way with random colors from an array.

    What I'm aiming at is a little more structured:

    STEP 1:

    I have an array with 10 colors:

    colors = new color[10];
    colors[0] = color(#62563D); // Infantry green
    colors[1] = color(#2C2B2D); // Parisian night blue
    colors[2] = color(#3E2224); // Purple heart
    colors[3] = color(#A49F9B); // Wild dove grey
    colors[4] = color(#684F40); // Brown
    colors[5] = color(#5C573D); // Moss green
    colors[6] = color(#B9897F); // Pink
    colors[7] = color(#24283B); // Dark blue
    colors[8] = color(#1F1D20); // Black
    colors[9] = color(#C5A9A2); // Brazilian clay
    

    I have 5 arrays with 3 values each:

    void instruments() {
    
      int[] guitar = new int[2];
        guitar[0] = 30; // 30%
        guitar[1] = 60; // 60%
        guitar[2] = 10; // 10%
    
      int[] trumpet = new int[2];
        trumpet[0] = 10;
        trumpet[1] = 30;
        trumpet[2] = 60;
    
      int[] contraBass = new int[2];
        contraBass[0] = 40;
        contraBass[1] = 40;
        contraBass[2] = 20;
    
      int[] flute = new int[2];
        flute[0] = 5;
        flute[1] = 15;
        flute[2] = 80;
    
      int[] drum = new int[2];
        drum[0] = 30;
        drum[1] = 40;
        drum[2] = 30;
    }
    

    Before the hexagon figure is being built, I want to press a button, which:

    • is connected with 1 array

    • collects all 3 percentage values from that array

    • add 3 random colors from the color array to the percentage values in random order

    • distribute those values into the hexagon figure by percentages, so guitar[0] will be 30 % represented, guitar[1] will be 60 % represented etc.

    • Place colors next to same colored neighbors with a percentage of 80 %

    STEP 2:

    Whenever I press another button connected with another array, I want it to override the color percentages with the new ones. So the created structures remains, but the colors change.

    So, how do I do that? ;)

  • The button is connected with 1 array? Or with one hexagon?

  • With 1 array. But it will distribute values to all available hexagons.

Sign In or Register to comment.