Consistent patterns when using random

I am designing a generative wreath. In it i want to randomly add a berry to the end of needles some of the time. However, the random() function is producing consistent patterns (see lines of berries in the image), usually in the same area as well as concentrating berries while leaving large areas without any. I have tried the following ways and they all produce similar results.

this is the pertinent code for the generation of branches and the vertex points in the branches are where the needles emerge from and the tip of the needle is the coordinate for the berry.

//start by making the underlying branches
  for(int i=0; i<numBranch; i++){
    float radius = minBranchRad + (i * 20);
    //float radius = (minBranchRad + (i * 10)) + random(10, 35);
    int resolution = floor(random(155,200));      //how many points along the circle path
    float radInt = random(0.1, 1.2);
    ArrayList<PVector> branchPts = new ArrayList<PVector>();
    for(float angle=0.0; angle<TWO_PI; angle+=TWO_PI/resolution){
      float xOff = cos(angle) * radInt + 1;
      float yOff = sin(angle) * radInt + 1;
      float radAmp = map(noise(xOff, yOff), -1.0, 1.0, 0.5, 1);
      branchPts.add(new PVector(cos(angle) * radius * radAmp, sin(angle) * radius * radAmp, angle));
    }
    branches.add(new Branch(resolution, radius, branchPts));
  }
 
  //for each branch, make a corresponding number of needles
  for(int j=0; j<branches.size(); j++){
    Branch b = branches.get(j);
    for(int k=0; k<b.ptCoords.size(); k++){
      float nLength = random(45, 65);    //get a length
      float nAngle;                       //get an angle
      if(k % 2 == 0){
        nAngle = random(60, 80);
      } else{
        nAngle = random(100, 125);
      }
      int shade = colorArray[2];
      boolean hasBerry = false;
      if(randNormal() <= 0.38){
        hasBerry = true;
      }
      needles.add(new Needle(j, nLength, nAngle, hasBerry, shade));

//basic random function
if(random(1) <= 0.173){
  hasBerry = true;
}

//averaged random funciton
float randNormal() {
  float sum = 0;
  int div = 6;
  for (int i=0; i<div; i++) {
    sum += random(1);
  }
  return sum / div;
}

How can i get a more randomized result with few to no patterns and get full coverage?

2 Likes

Hi @travis.stdenis :slightly_smiling_face:

You could play with randomGaussian(). This gives a nice distribution.

Also, of note, it appears in current setup of your code you have the berries syntactically connected to the needles.
Keeping the needles and berries in separate loops gives you more leeway to make adjustments. As well as reflects the actual construction of a wreath where berries sit on top of the pine.

size (400, 400);
background(255);
noStroke();

for (int i = 0; i < 360; i+=2) {
  float angle = radians(i);
  float x = width/2;
  float y = height/2;
  
  float radius = 125;
  float x2 = x + sin(angle) * radius + randomGaussian() * 15;
  float y2 = y + cos(angle) * radius + randomGaussian() * 10;
  
  fill(#AA0303);
  ellipse (x2, y2, 5, 5);
}

I recently read this essay by Tyler Hobbs about probability. It’s interesting!

:nerd_face:

4 Likes

Yes, i wanted them to appear at the tip of the needles. It works when there are fewer needles and you can see where they are attached. But I suppose with so many needles, it doesn’t matter and they can just be overlayed. I’ll relook at an option with a scattered approach like this.