steve-wang-generative

Steve Wang's Generative Flower

by Steve Wang We wrote the code in p5.js and the code was written in Javascript

A note from Dr. Bell: try looking at this at different times of day. It varies according to time.

This is the code that was used.

//3 improvements made
//do allignment 
var time = 0;
let colors = ["black", "gray", "red", "white"];
let shapes = ["ellipse", "rect", "triangle"];
 
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 = (angle * Math.PI) / 180;
    return new Point(
      this.x + distance * Math.sin(r),
      this.y + distance * Math.cos(r)
    );
  }
}
 
class Leaf{
constructor(positionOfLeaf,rotation){
this.leafXY=positionOfLeaf;
this.rotation=rotation
}
draw(){
  translate(this.leafXY.x,this.leafXY.y)
  rotate(this.rotation)
bezier(0,0, 0-47, 0, 0-35, 0+40, 0, 0);
line(0,0,0-34,0+16);
line(0-8,0+0.5,0-12,0+5.5);
line(0-6,0+6.5,0-12,0+5.5);
line(0-17,0+3,0-20,0+9);
line(0-13,0+12,0-20,0+10);
line(0-23,0+5,0-27,0+12.8);
line(0-20,0+16,0-27,0+12.8);
resetMatrix()
}
}
 
let canvasSize = new Point(1700, 800);
 
class Star {
  constructor() {
    this.starX = randomRange(0, canvasSize.x*5);
    this.starY = randomRange(0, canvasSize.y*5);
    this.starColor = randomRange(190, 255);
  }
  draw() {
    scale(0.6)
    this.starColor = randomRange(190, 255);
    fill(color(this.starColor, this.starColor, 0));
    noStroke();
    circle(28 + this.starX, 39 + this.starY, 27);
    triangle(
      18 + this.starX,
      29 + this.starY,
      28 + this.starX,
      14 + this.starY,
      38 + this.starX,
      29 + this.starY
    );
    triangle(
      18 + this.starX,
      29 + this.starY,
      3 + this.starX,
      39 + this.starY,
      18 + this.starX,
      49 + this.starY
    );
    triangle(
      18 + this.starX,
      49 + this.starY,
      28 + this.starX,
      64 + this.starY,
      38 + this.starX,
      49 + this.starY
    );
    triangle(
      38 + this.starX,
      49 + this.starY,
      53 + this.starX,
      39 + this.starY,
      38 + this.starX,
      29 + this.starY
    );
    resetMatrix();
  }
}
 
class RandomShape {
  constructor(x) {
    this.position = x;
    this.shape = pick(shapes);
    this.color = pick(colors);
    this.size = randomRange(10, 100);
    this.width = this.size;
    this.height = this.size;
  }
  draw() {
    if (this.shape == "ellipse") {
      fill(this.color);
      ellipseMode(CENTER);
      ellipse(this.position.x, this.position.y, this.width, this.height);
    }
 
    if (this.shape == "rect") {
      fill(this.color);
      ellipseMode(CENTER);
      rect(this.position.x, this.position.y, this.width, this.height);
    }
    if (this.shape == "triangle") {
      fill(this.color);
      ellipseMode(CENTER);
      triangle(
        this.position.x,
        this.position.y,
        this.position.x + this.width / 2,
        this.position.y + this.height,
        this.position.x + this.width,
        this.position.y
      );
    }
  }
}
 
function pick(inputArray) {
  return inputArray[Math.floor(inputArray.length * Math.random())];
}
 
function randomRange(min, max) {
  return min + (max - min) * Math.random();
}
 
function setup() {
  time= hour();
  createCanvas(canvasSize.x, canvasSize.y);
  frameRate(20);
}
 
function buildArray(n, fillFunction) {
  let outputArray = [];
  for (let i = 0; i < n; i++) {
    outputArray.push(fillFunction(i));
  }
  return outputArray;
}
 
function gridPattern(nOfRows, nInRow, itemX, itemY, startX, startY) {
  let yP = startY;
  let returnA = [];
  for (let i = 0; i < nOfRows; i++) {
    yP += itemY + 2;
    for (let b = 0; b < nInRow[i]; b++) {
      returnA.push(new Point((itemX + 5) * b + startX, yP));
    }
  }
  return returnA;
}
 
function randomPattern(nOfItems, minX, minY, maxX, maxY) {
  let returnA = [];
  for (let i = 0; i < nOfItems; i++) {
    returnA.push(new Point(randomRange(minX, maxX), randomRange(minY, maxY)));
  }
  return returnA;
}
 
function crossPatterns(nOfCrosses, crossPosition, widthOfCross, shapeSize) {
  let realShapeSize = shapeSize + 2;
  let returnArray = [];
  let angle = 0;
  for (let i = 0; i < nOfCrosses; i++) {
    returnArray.push(new Point(crossPosition[i].x, crossPosition[i].y));
    for (let b = 0; b < 4; b++) {
      angle += 90;
      if (b == 0) {
        angle = 0;
      }
      for (let a = 0; a <= widthOfCross[i]; a++) {
        returnArray.push(
          crossPosition[i].moveByAngle(angle, realShapeSize * a)
        );
      }
    }
  }
  return returnArray;
}
 
function circularPositions(nOfCircle, positions, nOfShapes, cSize) {
  let arrayToReturn = [];
  for (let i = 0; i < nOfCircle; i++) {
    let positionArray = buildArray(
      nOfShapes[i],
      (b) => new Point(positions[i].x, positions[i].y)
    );
    let testCircle = circlePattern(cSize, positionArray);
    arrayToReturn = arrayToReturn.concat(testCircle);
  }
  return arrayToReturn;
}
 
function circlePattern(cSize, cPosition) {
  let angle = 360 / cPosition.length;
  return cPosition.map((p, i) => {
    return p.moveByAngle(i * angle, cSize);
  });
}
 
function duplicateArray(times, arrayToCopy) {
  let returnArray = [];
  for (let i = 0; i < times; i++) {
    returnArray.push(arrayToCopy);
  }
  return returnArray;
}
 
//Replace in arrow function in 156
let reducer = (previousValue, currentValue) => previousValue + currentValue;
 
function addingWholeArray(arrayToAdd) {
  return arrayToAdd.reduce(reducer);
}
 
let i = 0;
 
class fantasticFlower {
  constructor(flowerXY,flowerNumberCounter) {
    this.flowerX = flowerXY.x;
    this.flowerY = flowerXY.y;
    this.flowerColor = pick(colors);
    this.petalsColor = pick(colors);
    this.flowerSize = randomRange(10, 45);
    this.petalWidth = randomRange(10, 30);
    this.petalHeight = randomRange(this.flowerSize-35, 55);
    if (flowerNumberCounter==1){
    this.petalWidth *= 11;    
    this.petalHeight *= 15;
    this.petalsColor = "yellow";
    this.flowerColor = "orange";
    this.flowerX = randomRange(100,800);
    this.flowerY = randomRange(200,400);
        }
    if (flowerNumberCounter==2){
  this.flowerSize *=1
    this.petalWidth *= 6;    
    this.petalHeight *= 9;
    this.petalsColor = "magenta";
    this.flowerColor = "blue";
    this.flowerX = randomRange(810,1600);
    this.flowerY = randomRange(200,400);
        }
    this.nOfPetals = randomRange(1, 10);
    this.nOfLeaves=randomRange(1, 5)
    this.counterForLeafColor=1
    this.counterForPetalHeight=1
    this.leafXY=new Point(this.flowerX+10,this.flowerY+6)
    this.stemLeaf=[]
    this.stemSize=0
    this.yToAddToLeaf=0
    this.BellLeaf=[new Leaf(new Point(this.flowerX+35,this.flowerY+25),0), new Leaf(new Point(this.flowerX-30,this.flowerY+25),-90)]
    this.leafToConcat=[]
    for (let i = 0; i < this.nOfLeaves; i++) {
      if (i%2==0){this.yToAddToLeaf=30*i;
this.BellLeaf=this.BellLeaf.concat([new Leaf(new Point(this.flowerX+35,this.flowerY+25+this.yToAddToLeaf),0)])}
      else{
      this.leafToConcat=[ new Leaf(new Point(this.flowerX-30,this.flowerY+25+this.yToAddToLeaf),-90)]}
this.BellLeaf=this.BellLeaf.concat(this.leafToConcat)
    }
          if (this.nOfLeaves>2){
  this.stemSize=this.petalHeight*4+120}
    else{this.stemSize=this.petalHeight*3}
    for (let i = 0; i < this.counterForLeafColor; i++) {
if(this.flowerColor==this.petalsColor){this.petalsColor=pick(colors);this.counterForLeafColor+=1}}
    if (this.stemSize<50){this.stemSize=150}
    this.stemWidth=this.stemSize/45
        if (flowerNumberCounter==1){
        this.stemWidth*=1.1
        }
     if (flowerNumberCounter==2){
        this.stemWidth*=1.1
        }
  }
  draw() {
   this.BellLeaf.forEach(x=>x.draw())
    fill("green");
      rect(this.flowerX, this.flowerY, this.stemWidth,this.stemSize);
    resetMatrix()
      i += 1
    translate(this.flowerX, this.flowerY);
    rotate(i);
    fill(this.petalsColor);
    let petalsRotate = 360 / this.nOfPetals;
    for (let a = 0; a < this.nOfPetals; a++) {
      rotate(petalsRotate);
      ellipse(0, -10, 10 + this.petalWidth, 20 + this.petalHeight);
    }
 
    fill(this.flowerColor);
    circle(0, 0, this.flowerSize);
    circle(0, 0, this.flowerSize - 10);
    let drawLeaf=new Leaf(new Point(this.flowerX,this.flowerY),0)
    drawLeaf.draw();
    resetMatrix();
  }
}
 
function arrayRandomPicker(arraytoPickFrom1, arraytoPickFrom2) {
  if (arraytoPickFrom1.length != arraytoPickFrom2.length) {
    return "The legnth of both arrays are not the same", false;
  }
  let returnArray = [];
  let pick = 0;
  for (let b = 0; b < arraytoPickFrom1.length; b++) {
    pick = randomRange(0, 2);
    if (pick == 0) {
      returnArray.push(arraytoPickFrom1[b]);
    } else {
      returnArray.push(arraytoPickFrom2[b]);
    }
  }
  return returnArray;
}
 
function iInLoopedArray(shorterArray, longerArray) {
  let returnArray = [];
  for (let a = 0; a < longerArray.length; a++) {
    returnArray.push(shorterArray[a % shorterArray.length]);
  }
  return returnArray;
}
 
class FlowerField {
  constructor(patternName, positionArray, itemSize, widthArray) {
    if (positionArray.length != widthArray.length) {
      if (positionArray.length < widthArray.length) {
        this.widthArray = widthArray;
        this.positionArray = iInLoopedArray(positionArray, widthArray);
      } else {
        this.widthArray = iInLoopedArray(widthArray, positionArray);
        this.positionArray = positionArray;
      }
    } else {
      this.positionArray = positionArray;
      this.widthArray = widthArray;
    }
    this.itemSize = itemSize;
 
    this.newPositions = this.adjustPosition(
      patternName,
      canvasSize,
      this.positionArray,
      this.itemSize,
      this.widthArray
    );
    this.shapesXY = buildArray(this.newPositions.length, this.XYSet);
    this.shapesNow = this.shapesXY.map((x) => new RandomShape(x));
    this.flowersXY = buildArray(this.newPositions.length, this.XYSet);
    this.flowersArray = this.shapesXY.map((x) => new fantasticFlower(x));
    this.flowersArray.forEach((b, i) => {
      this.flowersArray[i].flowerX = this.newPositions[i].x;
    });
 
    this.flowersArray.forEach((b, i) => {
      this.flowersArray[i].flowerY = this.newPositions[i].y;
    });
 
    this.shapesNow.forEach((b, i) => {
      this.shapesNow[i].position = this.newPositions[i];
    });
 
    this.flowersArray = arrayRandomPicker(this.flowersArray, this.shapesNow);
    return this.flowersArray;
  }
  help(patternName) {
    console.log("patternHelp Output:");
    console.log(
      "If unsure what format to type arguments in here are the formats for arguments: (string, Point class, array filled with Point class, number, number, array)"
    );
    console.log(
      "These are the instructions for:",
      patternName,
      "Instructions will alow you to understand what to type for each argument"
    );
    if (patternName.includes("cross")) {
      console.log(
        "(Specify Pattern name,totalItems(number), Positon of crosses, Position between each shape, itemSize, Width of cross"
      );
    } else if (patternName.includes("circle")) {
      console.log(
        "(Specify Pattern name, totalItems, Positon of circles, Position between the shapes that outline circle, itemSize, An array with the amount of items that will outline each circle"
      );
    } else if (patternName.includes("random")) {
      console.log(
        "(Specify Pattern name, totalItems, Invalid because random positions,Invalid because randomPosition, itemSize, Invalid because each item will be on their own"
      );
    } else if (patternName.includes("grid")) {
      console.log(
        "(Specify Pattern name, totalItems, where to start drawing grid (array with a point class), the size of each item (number), nO amount of items on each row"
      );
    } else {
      console.log(
        "Invalid pattern name: the only patterns are cross, circle, grid, random",
        "End of pattenHelp"
      );
      return false;
    }
    return "End of pattenHelp";
  }
  adjustPosition(
    patternName /*(string)*/,
    canvasSize /*(Point class)*/,
    midPoints /*(array filled with Point class)*/,
    itemSize /*(number)*/,
    PatternWidth /*(array)*/
  ) {
    if (
      patternName.includes("cross") ||
      patternName.includes("circle") ||
      patternName.includes("random") ||
      patternName.includes("grid")
    ) {
      if (patternName.includes("cross")) {
        let nOfCrosses = midPoints.length;
        let totalWidths = addingWholeArray(PatternWidth);
        let shapeSize = itemSize;
        let returnArray = [];
        return crossPatterns(nOfCrosses, midPoints, PatternWidth, shapeSize);
      }
 
      if (patternName.includes("circle")) {
        let arrayToReturn = [];
        let shapeSize = itemSize;
        let nOfCircle = midPoints.length;
        let nOfShapes = PatternWidth;
        console.log(nOfCircle);
        let ps = circularPositions(
          nOfCircle,
          midPoints,
          PatternWidth,
          shapeSize
        );
        console.log(ps);
        for (let b = 0; b < ps.length; b++) {
          arrayToReturn = arrayToReturn.concat(ps[b]);
        }
        console.log(arrayToReturn);
        return arrayToReturn;
      }
 
      if (patternName.includes("random")) {
        let arrayToReturn = [];
        for (let i = 0; i < midPoints.length; i++) {
          let minXY = new Point(itemSize + 10, itemSize + 10);
          let maxX = 0;
          let maxY = 0;
          maxX = itemSize;
          maxY = itemSize;
          if (itemSize > canvasSize.x || itemSize > canvasSize.y) {
            if (itemSize > canvasSize.x) {
              maxX = canvasSize.x;
            }
            if (itemSize > canvasSize.y) {
              maxY = canvasSize.y;
            }
          }
 
          let maxXY = new Point(canvasSize.x, canvasSize.y);
          let arrayToJoin = randomPattern(
            PatternWidth[i],
            minXY.x,
            minXY.y,
            maxXY.x,
            maxXY.y
          );
          arrayToReturn = arrayToReturn.concat(arrayToJoin);
        }
        return arrayToReturn;
      }
 
      if (patternName.includes("grid")) {
        let arrayToReturn = [];
        for (let i = 0; i < midPoints.length; i++) {
          let rowNumber = PatternWidth[i];
          let gridInfo = duplicateArray(rowNumber, PatternWidth[i]);
          let itemXYsizes = new Point(itemSize, itemSize);
          let startXY = new Point(midPoints[i].x, midPoints[i].y);
          let arrayToJoin = gridPattern(
            gridInfo.length,
            gridInfo,
            itemXYsizes.x,
            itemXYsizes.y,
            startXY.x,
            startXY.y
          );
          arrayToReturn = arrayToReturn.concat(arrayToJoin);
        }
        return arrayToReturn;
      } else {
        console.log(
          "Invalid patternName",
          "If help needed please type: patternHelp(patternName)"
        );
        return false;
      }
    }
  }
  XYSet(i) {
    return new Point(
      randomRange(0, canvasSize.x),
      randomRange(0, canvasSize.y)
    );
  }
}
 
class SkyColor{
  constructor(time){
  this.time=time
  this.colorSet=0
  this.starOrNot=""
  }
  draw(){
  if (this.time>6 && this.time<17){this.colorSet=50*(this.time-6)}
  else if (this.time>17){this.colorSet=225-(50*(this.time-17))}
  else (this.colorSet=0)
if(this.time>21||this.time<6){this.starOrNot="yes"}
 
return [0,this.colorSet,this.colorSet,this.starOrNot]
}
 
star(){
 
  this.starX = randomRange(0, canvasSize.x);
    this.starY = randomRange(0, canvasSize.y);
   this.starColor = randomRange(190, 255);
    this.starColor = randomRange(190, 255);
    fill(color(this.starColor, this.starColor, 0));
    noStroke();
    circle(28 + this.starX, 39 + this.starY, 27);
    triangle(
      18 + this.starX,
      29 + this.starY,
      28 + this.starX,
      14 + this.starY,
      38 + this.starX,
      29 + this.starY
    );
    triangle(
      18 + this.starX,
      29 + this.starY,
      3 + this.starX,
      39 + this.starY,
      18 + this.starX,
      49 + this.starY
    );
    triangle(
      18 + this.starX,
      49 + this.starY,
      28 + this.starX,
      64 + this.starY,
      38 + this.starX,
      49 + this.starY
    );
    triangle(
      38 + this.starX,
      49 + this.starY,
      53 + this.starX,
      39 + this.starY,
      38 + this.starX,
      29 + this.starY
    );
  }
}
 
let nOfFlower=100
let flowersArray = buildArray(
  nOfFlower,
  (x) =>
    new fantasticFlower(new Point(randomRange(0, 1700), randomRange(0, 800)),nOfFlower-x)
);
 
let starArray = buildArray(90, (x) => new Star());
 
function draw() {
 let backgroundColor=new SkyColor(time);
 let backgroundColor2=backgroundColor.draw()
    background(backgroundColor2[0], backgroundColor2[1], backgroundColor2[2]);
  if (backgroundColor2[3]=="yes"){
   starArray.forEach((x) => x.draw());}
  stroke(2);
  flowersArray.forEach((x) => x.draw());
}
 
function shapeFromPoints(pointArray) {
  beginShape();
  pointArray.forEach((p) => vertex(p.x, p.y));
  endShape(CLOSE);
}
 
function buildArray2(n, fillFunction) {
  let outputArray = [];
  for (let i = 0; i < n; i++) {
    outputArray.push(fillFunction);
  }
  return outputArray;
}
 
function randomRange(min, max) {
  return Math.floor(min + (max - min) * Math.random());
}
 
function head(array) {
  return array.splice(0, 1)[0];
}
 
//Last item of array
 
function last(array) {
  return array.splice(array.length - 1, 1)[0];
}

  • steve-wang-generative.txt
  • Last modified: 2022/02/01 08:22
  • by renick