Flower Bot

Built with p5.js

A few months ago, when the weather was still nice and sunny, I was sat out in the garden reading Daniel Shiffman's 'Learning Processing'. I got to exercise 7-6 which suggested creating a design for a flower and I thought replica watches uk why not. So thinking that I could pretend that I was doing it to generate some pictures for my nieces (who did by the way like the images that I sent them - well they are both under 5), I grabbed my Macbook and settled down to code a few flowers.

So when Daniel then did a live stream on using Processing with Node.js to make a twitter bot, I knew which sketch to try it out with.

As was recommended during the stream I created a new twitter account @BothNT and I started out tweeting an image every 15 minutes. Although I have recently scaled that back to one every 4 hours ... mostly for my own sanity as I'm keeping an eye swiss replica watches the account from my main twitter account.

Annoyingly enough this flowers bot appears to have been getting more likes and retweets than anything on my main account during the same period and now that I've had a couple of requests to post the code behind it, I though that it was time to add a little bit of a write up on here.

For the processing sketch I created a flower class and then used it to generate between 1 and 25 flowers per sketch. Saving off the resulting image. I ended up trying out Processing's Spline Curve to draw the stem, although I'd look for a rolex replica different solution next time.

The code was writen to draw a quick sketch, not for sharing. So apologies for how badly it is written :-)

The twitter bot is made using Node.js with the Twit package and Processing v3.

The Processing code:
void setup() {
  size(800, 600);
  background(230, 230, 255, 100);
  int count = (int)(random(1,26));
  Flower[] flowers = new Flower[count];
  
  for(int i = 0; i< flowers.length; i++){
    flowers[i] = new Flower(random(100, width-100), random(100, height-100), (int)random(4,13), color(random(255), random(255), random(255), random(100, 225)), (int)random(1, 4));
    flowers[i].drawFlower();
  }
  
  save("output.png");
  exit();
}  
 
class Flower {
	
  // The x, y location on the screen. The number of petals, 
  // the colour of the petals and then number of layers of petals.
  float x;
  float y;
  int numPetals;
  color c;
  int levels;
	
  // To hold the calculated flower height 
  float flowerHeight;
	
  // To vary the alpha applied to each layer of petals.
  float a;
  float aDif;
	
  // Thickness of the stem.
  float thickness;
	
  // Variables for the spline curve
  float Bx;
  float By;
  float Tx;
  float Ty;
  float BCx;
  float BCy;
  float TCx;
  float TCy;
  
  // Angle variable used for rotation
  // during the petal drawing.
  float ang;
	
  // Flower Constructor
  Flower(float x, float y, int numPetals, color c, int levels) {
    this.x = x;
    this.y = y;
    this.numPetals = numPetals;
    this.c = c;
    this.levels = levels;

    flowerHeight = height - y;
    aDif = 255 - alpha(c);
    thickness = random(5, 10);
		
    Bx = random(-15, 15);
    By = flowerHeight;
    Tx = -thickness*0.5;
    Ty = 0;
    BCx = random(-100, 100);
    BCy = random(flowerHeight+450, flowerHeight+580);
    TCx = random(-100, 100);
    TCy = random(flowerHeight-50, flowerHeight-10);
    
    ang = 360 / numPetals;
  }

  void drawFlower() {
    // https://www.processing.org/reference/pushMatrix_.html
    pushMatrix();
		
    // https://www.processing.org/reference/translate_.html
    translate(x, y);



    // Draw the stem
    // -------------
    stroke(0, random(50, 200), 0);
    strokeWeight(random(5, 10));
		
    // https://www.processing.org/tutorials/curves/
    // https://www.processing.org/reference/curve_.html
    curve(TCx, TCy, Tx, Ty, Bx, By, BCx, BCy);



    // Draw the petals
    // ---------------
    rotate(radians(random(360)));
    noStroke();  
		
    // Each flower can have up to 3 layers/levels of petals 
    if (levels >= 3) {
      // 3rd layer petals - outer
      fill(c);
      for (float i = 1; i <=numPetals; i++) {
        ellipse(0, -55, 50, 130);
        rotate(radians(ang));
      }
    }

    if (levels >= 2) {
      // 2nd Layer petals - middle
      a = constrain(alpha(c)+(aDif*0.5), alpha(c), 255);
      fill(red(c), green(c), blue(c), a);
      rotate(radians(ang/levels));
      for (float i = 1; i <=numPetals; i++) {
        ellipse(0, -35, 50, 115);
        rotate(radians(ang));
      }
    }

    // 1st layer petals - inner
    rotate(radians(ang/levels));
    a = constrain(alpha(c)+(aDif*0.9), alpha(c), 255);
    fill(red(c), green(c), blue(c), a);

    for (float i = 1; i <=numPetals; i++) {
      ellipse(0, -25, 50, 100);
      rotate(radians(ang));
    }



    // Draw the flower centre
    // ----------------------
    // Change to HSB mode and then colour the centre of the flower.
    colorMode(HSB, 360, 100, 100);
    fill(64, random(30, 100), random(80, 100));
    float dia = random(35, 60);
    ellipse(0, 0, dia, dia);
		
    // Change back to RGB colour mode.
    colorMode(RGB, 255);
		
    // https://www.processing.org/reference/popMatrix_.html
    popMatrix();
  }
}
The twitter bot code:
console.log("Twitter bot starting");

var Twit = require('twit');
var config = require('./config');
var exec = require('child_process').exec;
var fs =  require('fs');

var T = new Twit(config);

tweetIt();
setInterval(tweetIt, 1000*60*15);

function tweetIt(){
	// Build the command for execution on a Mac.
	var cmd = 'processing-java --sketch=`pwd`/Flowers5_objs --run'
	
	// On Windows I used:
	// var cmd = '"C:\\Program Files\\processing-3.01\\processing-java" --sketch=C:\\tasks\\node6\\Flowers5_objs --run'
	
	exec(cmd, processing);
	
	function processing(){
	  var b64content = fs.readFileSync('Foldername/output.png', { encoding: 'base64' });
		T.post('media/upload', { media_data: b64content}, uploaded);
		
		function uploaded(err, data, response){
			var id = data.media_id_string;
			var tweet = {
				status: 'Node.js & Processing',
				media_ids: [id]
			}
			T.post('statuses/update', tweet, function(err, data, response) {
			  if(err){
			  	console.log(err);
			  } else {
			  	console.log("Twitter Updated: " + Date());
			  }
			});	
		}
	}
}
The Config.js code :
module.exports = {
    consumer_key:         '******************************************'
  , consumer_secret:      '******************************************'
  , access_token:         '******************************************'
  , access_token_secret:  '******************************************'
}

Sources that you should check out:

Shiffman D. (2015) Learning Processing. 2nd Ed. Burlington, MA.: Morgan Kaufmann.
Functions, P129, Exercise 7-6 "Create a design for a flower."

shiffman (2015) Making Image Twitter Bots with Node and Processing. Available at: https://www.youtube.com/watch?v=KNsFrAnzSN4 (Accessed: 12 Nov 2015).

At the same time, the swiss replica watches US Pacific Command spokesman Dave Benham confirmed to the media, the headquarters in Hawaii time 15 at 11:21 (Beijing time at 5:21 on the 16th) to detect North replica watches Korea in the missile test The Benham said the missile had exploded immediately replica watches uk after the launch. The US military is assessing what kind of missiles the test shot is.