Oliver Wang's Generative Flower

by oliver wang

let myWidth = 1700;
let myHeight = 800;
 
function setup() {
  createCanvas(myWidth, myHeight);
  noLoop();
}
 
function randomRange(min, max) {
  return min + (max - min) * Math.random();
}
 
class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
  move(xDistance, yDistance) {
    return new Point(this.x + xDistance, this.y + yDistance);
  }
  moveByAngle(angle, distance) {
    let r = (-1 * (angle + 180) * Math.PI) / 180;
    return new Point(
      this.x + distance * Math.sin(r),
      this.y + distance * Math.cos(r)
    );
  }
}
 
function randomPoint(xMin, xMax, yMin, yMax) {
  return new Point(randomRange(xMin, xMax), randomRange(yMin, yMax));
}
 
function buildArray(n, fillFunction) {
  let outputArray = [];
  for (let i = 0; i < n; i++) {
    outputArray.push(fillFunction(i));
  }
  return outputArray;
}
 
function shapeFromPoints(pointArray) {
  beginShape();
  pointArray.forEach((p) => vertex(p.x, p.y));
  endShape(CLOSE);
}
 
function pointsForConvexShape(
  centerPoint,
  noOfPoints,
  minDistance,
  maxDistance,
  minRotation,
  maxRotation
) {
  let angles = low2HighSort(
    buildArray(noOfPoints, (x) => randomRange(minRotation, maxRotation))
  );
  let distances = buildArray(noOfPoints, (x) =>
    randomRange(minDistance, maxDistance)
  );
  let points = angles.map((x, i) => {
    return centerPoint.moveByAngle(x, distances[i]);
  });
  return points;
}
 
function buildArray(n, fillFunction) {
  let outputArray = [];
  for (let i = 0; i < n; i++) {
    outputArray.push(fillFunction(i));
  }
  return outputArray;
}
 
function pick(inputArray) {
  return inputArray[Math.floor(inputArray.length * Math.random())];
}
 
class FantasticFlower {
  constructor(x, y, size, randomOrNot, inputColor) {
    this.shape = ["ellipse", "circle", "square", "rect"];
    this.colors = ["lightGreen", "yellow", "white", "pink", "lavender"];
    this.x = x;
    this.y = y;
    this.size = size;
    this.petal = Math.floor(Math.random() * 10);
    this.randomOrNot = randomOrNot;
    this.inputColor = inputColor;
  }
  draw(flowerPoint) {
    translate(flowerPoint.x, flowerPoint.y);
    circle(0, 0, 50);
    stroke(0);
    let shapeSelector = pick(this.shape);
    let colorSelector = pick(this.colors);
    let rotation = 0;
 
    if (colorSelector == "red" && this.x < 600) {
      this.petal = 5;
    } else if (colorSelector == "lavender" || this.x >= 600) {
      this.petal = 9;
    } else if (colorSelector != "yellow" || this.x >= 1200) {
      this.petal = 7;
    }
    if (this.petal == 1) {
      this.petal += 1;
    }
    switch (this.petal) {
      case 10:
        rotation = 4;
        break;
      case 9:
        rotation = 3.5;
        break;
      case 8:
        rotation = 3.25;
        break;
      case 7:
        rotation = 3;
        break;
      case 6:
        rotation = 2.75;
        break;
      case 5:
        rotation = 2.5;
        break;
      case 4:
        rotation = 2;
        break;
      case 3:
        rotation = 1.75;
        break;
      case 2:
        rotation = 1.5;
        break;
    }
 
    translate(this.x, this.y);
    let r = 255;
    let g = 255;
    let b = 255;
    for (let i = 0; i < this.petal; i++) {
      if (this.randomOrNot != "random" && this.randomOrNot == "notRandom") {
        let c = this.inputColor;
        fill(c);
      } else if (colorSelector == "lavender") {
        fill(204, 153, 255);
      } else {
        let c = color(colorSelector);
        fill(c);
      }
      switch (shapeSelector) {
        case "rect":
          rect(0, 0, this.size, this.size / 2);
          fill(g, b, r);
          rect(5, 4, this.size / 2, this.size / 3);
          break;
        case "square":
          square(0, 0, this.size);
 
          fill(b, r, g);
          square(10, 5, this.size / 2);
          rect(50, 0, this.size / 2, this.size / 3);
          break;
        case "circle":
          circle(10, 0, this.size);
          fill(r, b, g);
          circle(10, -10, this.size / 2);
          break;
        case "ellipse":
          ellipse(0, 0, this.size, this.size / 2);
          fill(r, g, b);
          ellipse(0, 0, this.size / 1.4, this.size / 2);
      }
 
      rotate(PI / rotation);
      fill("yellow");
      circle(0, 0, this.size / 2);
      fill("orange");
      circle(0, 0, this.size / 3);
      r -= 20;
      b -= 40;
      g -= 20;
    }
    resetMatrix();
  }
}
 
let  greenFlowers = buildArray(
  90,
  (i) => new FantasticFlower(0, 0, 30, "notRandom", "lightGreen")
);
 
let redFlowers = buildArray(
  90,
  (i) => new FantasticFlower(0, 0, 30, "notRandom", "red")
);
 
let randomFlowers = buildArray(
  36,
  (i) =>
    new FantasticFlower(
      0,
      0,
      40,
      "random",
      "haha"
    )
);
let last5RedFlowers = redFlowers.slice(295);
last5RedFlowers.forEach((x) => (x.size = x.size * 2));
 
let allFlowers = redFlowers.concat(randomFlowers, last5RedFlowers);
 
let p1 = new Point(myWidth / 3, myHeight / 2);
let p2 = p1.moveByAngle(0, 300);
 
let anglePoints1 = buildArray(90, (i) => {
  return p1.moveByAngle(i * 10, 10+(3 * i));
});
 
let anglePoints2 = buildArray(90, (i) => {
  return p1.moveByAngle(i * 10, 350);
});
 
let anglePoints3 = buildArray(90, (i) => {
  return p1.moveByAngle(i * 10, -5-(3 * i));
});
 
 
console.log(anglePoints2);
 
function specialFlower (x, y){
let colors = ["lightBlue", "lightGreen", "aqua", "darkRed", "lightPink", "purple", "khaki", "gray", "orange", "red"]
 
translate(x, y)
for(let i = 0 ; i < colors.length ; i++){
  let colorPicker = colors[i]
fill(colorPicker)
square(0, 0, 50)
rotate(PI/5)
}
  fill(115, 94, 38)
  circle(0, 0, 20)
 
  resetMatrix()
 
}
 
let number = 1
 
function draw() {
  let X = (0.01) * frameCount % (-10 + height/2);
  let x = 1000
  background(11, 17, 107);
fill("white")
 textSize(20)
text("please click it", 10, 20)
 
}
 
function mouseClicked(){
switch(number){
  case 1:
  randomFlowers.forEach((x, i) => {
    x.draw(anglePoints2[i]);
  });
  number += 1
break;
case 2:
redFlowers.forEach((x, i) => {
    x.draw(anglePoints3[i]);
  });
number +=1
break;
case 3:
greenFlowers.forEach((x, i) => {
    x.draw(anglePoints1[i]);
  });
number+=1
break;
case 4:
 specialFlower(width/3, height/2)
number-=3
break;
}
}