sketch_200218a

sketch_200218a.pde


final int N = 100;
final int MAX_TRIAL = 1000;

int[] nPetalsList;
Flower[] flowerList;

void setup() {
  size(800, 800);
  nPetalsList = new int[] {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 5};
  initFlowerList();
  noLoop();
}

void initFlowerList() {
  
  flowerList = new Flower[200];
  
  for (int k = 0; k < flowerList.length; k++) {
    int trial = 0;
    while (trial < MAX_TRIAL) {
      int n = nPetalsList[(int)random(nPetalsList.length)];
      float r = random(24.0, 160.0);
      float x = random(-width / 2.0, width / 2.0);
      float y = random(-height / 2.0, height / 2.0);
      
      color[] palette = selectPalette();
      Flower newFlower = new Flower(new PVector(x, y), n, r, r / 10.0, palette);
      
      if (!intersects(flowerList, newFlower)) {
        flowerList[k] = newFlower;
        break;
      }
      
      trial++;
    }
    
    if (trial == MAX_TRIAL) {
      flowerList[k] = new Flower(new PVector(0.0, 0.0), 0, -1.0, -1.0, null);
    }
  }
}

void draw() {
  translate(width / 2.0, height / 2.0);
  
  background(24);
  
  for (Flower flower : flowerList) {
    pushMatrix();
    flower.draw();
    popMatrix();
  }

  filter(BLUR, 0.8);
}

void mousePressed() {
  initFlowerList();
  redraw();
}

void keyReleased() {
  saveFrame(String.format("frames/%s", timestamp("Project", ".png")));
}

static final String timestamp(final String name, final String ext) {
  return name + "-" + year() + nf(month(), 2) + nf(day(), 2) +
    "-" + nf(hour(), 2) + nf(minute(), 2) + nf(second(), 2) + ext;
}

color[] selectPalette() {
   if (random(1) < 0.1) {
     return new color[] {#BDFF42, #68E831, #E8E831, #FFEB36};
   } else {
     return new color[] {#6FE894, #87FF89, #97E86F, #D4FF7A};
   }
}

class Flower {
  int nPetals;
  PVector pos;
  float r;
  float petalRadius;
  color[] palette;
  Flower(PVector pos, int nPetals, float r, float petalRadius, color[] palette) {
    this.pos = pos;
    this.nPetals = nPetals;
    this.r = r;
    this.petalRadius = petalRadius;
    this.palette = palette;
  }
  
  void draw() {
    if (this.r < 0.0) {
      return;
    }
    
    pushMatrix();
    translate(this.pos.x, this.pos.y);
    
    pushMatrix();
    rotate(TWO_PI / nPetals / 6.0 * (int)random(7));
    
    for (int i = 0; i < palette.length; i++) {
      pushMatrix();
      scale(lerp(1.0, 0.75, (float)i / palette.length));
      noStroke();
      fill(palette[i]);
      for (int n = 0; n < nPetals; n++) {
        pushMatrix();
        float s = TWO_PI / nPetals * n + TWO_PI / nPetals / 2.0;
        translate(petalRadius * cos(s), petalRadius * sin(s));
        pushMatrix();
        rotate(TWO_PI / nPetals / 8.0);
        this.drawPetals(n);
        popMatrix();
        pushMatrix();
        rotate(-TWO_PI / nPetals / 8.0);
        this.drawPetals(n);
        popMatrix();
        popMatrix();
      }
      popMatrix();
    }
  
    popMatrix();
    popMatrix();
  }
  
  void drawPetals(int n) {
    beginShape();
      for (int k = 0; k < N; k++) {
        float t = (TWO_PI / nPetals * k / N) + (TWO_PI / nPetals * n);
        float r = this.r * pow(sin(t * (nPetals / 2.0)), 2.0);
        float x = r * cos(t);
        float y = r * sin(t);
        
        vertex(x, y);
      }
    endShape(CLOSE);
  }
  
  float getRadius() {
    return this.r + this.petalRadius;
  }
}

boolean intersects(Flower[] flowers, Flower newFlower) {
  for (Flower flower : flowers) {
    if (flower != null) {
      PVector diffVec = PVector.sub(flower.pos, newFlower.pos);
      float d = diffVec.mag();
      
      if (d < flower.getRadius() + newFlower.getRadius()) {
        return true;
      }
    }
  }
  return false;
}