Gradient 'rainbow' stroke

So I am working on a little project for school. I created an hexagon grid, but I want it to have this rainbow color pattern, beginning at the center. I worked with lines, so it actually uses stroke() to color. So to make it clear (hopefully): My hexagon pattern, built out of seperate lines, has to get a rainbow color pattern, starting at the center of the grid, spreading outwards.

https://www.google.nl/search?q=rainbow+radiant+pattern&client=firefox-b-ab&source=lnms&tbm=isch&sa=X&ved=0ahUKEwjvh8jDu7rPAhVCrxoKHfGNCXQQ_AUICCgB&biw=1536&bih=731#tbm=isch&q=rainbow+gradient+pattern&imgrc=0BOJ6fUvD8OiFM:

^This is what I mean by color pattern, starting at the 'center'. ^

I hope this is clear enough, it's hard to explain in english.

This is my code so far:

float[] hexagonX = new float[width];
float[] hexagonY = new float[height];

//scale factor to determine the size of the grid
float scaleF = 0.8;

void setup() {
 size(480, 640);
 background(0);
 stroke(255);
 smooth();
 noLoop();
}

void draw() { 
  //hexagon(width/2, height/2); <- Test Hexagon

  //loop for drawing an hexagon grid
  for(int i = 0; i < hexagonX.length; i ++){   
    for(int j = 0; j < hexagonY.length; j++){
      //for all the hexagons on the 'even' rows, the X-coördinate of every individual hexagon equals scaleF * (i*102)
      //for all the hexagons on the 'odd' rows, the X-coördinate of every individual hexagon equals scaleF * (51 + i * 102)
      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();
}

I really hope someone can help me out :D

Answers

  • Use hsb color mode. Map distance from centre to hue. Pass a colour parameter to your hexagon drawing code.

    Beware that hexagons share edges.

  • @DelanoAtID one problem is that your strategy for drawing hexs (left-to-right, top-to-bottom) and your strategy for coloring them (winding-out-from-center) don't match.

    @koogs described one way of solving this. If you draw all colored hexes fills first, then a grid of white lines of top in a second pass, this may give you what you want, although they will be concentric rings (not winding).

    Another way would be to make your "//loop for drawing an hexagon grid" actually draw winding out. Then you can increment color as you go in "natural" order, and you will get the ball-of-yarn effect rather than distance rings.

    1. find the center (width/2 / height/2).
    2. draw your first hexagon
    3. which is long, screen width or height? In your example, height.
    4. calculate how many hexagons wide/heigh it will take to reach that farthest edge -- that's how much windings you have to do to reach the edge. In your example, the answer is "7". Add 2-3 more loops to fill out the corners as well -- let's say 10.
    5. loop 10 times
    6. for each loop you will translate through drawing hexes at N, NE, SE, S, SW, NW, N. Everything can be done with relative "translate" commands. The first loop you have 6 hexes, then next 12, the next 18, the next 24....
    7. Keep a counter of what hex you are drawing. If you like, you can precompute how many total hexes you will draw, and use lerpColor to color the current hex based on the total. For example, center + 10 rings of hexes = 1 + 6 + 12 + 18 + 24 + 30 + 36 + 42 + 48 + 54 + 60 = 331 hexes (many at the outer edges will not appear on the screen).
  • edited October 2016

    Looking back at your question I think I was confused by the ball of yarn image you shared, @DelanoAtID, and I thought you wanted winding -- something like a rainbow that a hopping-qbert would create on hexes:

    HexWinders1

    ...but then realized you wanted line color, not fills:

    HexWinders2

    ...and perhaps just color in concentric circles, not winding! If all you want is concentric circles, @koogs had the right suggestion. Add this to your setup:

    colorMode(HSB, 360, 100, 100);
    

    ... and these two lines to your hexagon():

    float hue = 360 * sqrt( sq(x - width/2) + sq(y - height/2) ) / max(width/2,height/2);
    stroke(hue, 100, 100);
    

    ...to get this:

    HexRadial2

    If you want actual winding, like yarn, the geometric code is much more involved than a radial distance function, but it can be done. The trick is to not draw the hexes left-to-right, top-to-bottom. Instead, draw them in winding order (1,2,3,4 from the center) and increase the color gradient using lerp as you go -- as you can see in the numbering of the first image above.

Sign In or Register to comment.