Tim Dickson – Blog 14

In the final week of the semester, I continued to work on my generative system assignment. I still had to do the following:

  • Draw a sun that is displayed behind the clouds.
  • Put measurements on the thermometer and make it display the temperature of the current city.
  • Allow the user to change between cities with the arrow keys or buttons
  • Make the clouds move based on the current city’s wind speed.
  • Make the clouds continually generate, instead of stopping at 200
  • Determine the current condition and animate it.
  • Populate the animation with images of each existing city, as well as more cities depending on how much time I had.

I started off by looking at how to draw a sun. I could’ve drawn a bright circle in the sky, but I wanted to make it more animated, like it was constantly burning. I wasn’t sure where to start, so I looked online to see if anyone had done something similar for inspiration. I found an example on Open Processing, which did exactly what I wanted my sun to do except this one was done using processing rather than p5.js. After reading through the code, I was able to understand what was going on.

Processing Sun.png

I realised how similar processing was to p5.js and I was able to determine that:

  • void is the same as function.
  • size is the same as createCanvas.
  • All of the floats, ints, etc. needed to be turned into variables in p5.js
  • dist is a preset variable in p5.js so it wouldn’t work properly, I had to change its name to something else.

The example made the user press the spacebar to generate a new drawing every time, where I wanted mine to keep changing continuously so I left the loop in mine and didn’t put in any user control, I just followed the way that they drew it to get a similar effect. I decided to keep the sun in the same spot in each location instead of making it random as well, in case it were to show up in front of an object in the background image and not look as effective.

I then looked at drawing the measurements on the thermometer. I created a loop that would divide the height of the thermometer tube by 50 and draw a line in every instance. I wanted some form of numerical element though as well to make the identification easier so I thought about how I could do that. I remembered once using a formula that would check if a number was divisible by another number by determining if the remainder of the division was 0, so I looked that up and found the answer on W3 Schools. You can use a percentage sign to check the divisibility of a number like this:

if (number % 5 == 0) {

}

In this case, if the number variable divided by 5 returned a remainder of 0, it would therefore be divisible by 5 and would run whatever is inside the if statement. So this is what I used for my thermometer, if the number was divisible by 5 it would display it as text, else it would display it as a line. I then drew a box over the top of the red mercury on the thermometer, with a height that is controlled by the temperature. I tested it on several locations and the accuracy was perfect.

My assignment then looked like it was really starting to come together as you can see below, note that I took the cloud for loop out so that it only displayed one cloud and I could see what I was doing with the sun and temperature. I also removed the temperature text as I had determined that my thermometer was working correctly.

Generative System F.png

I then looked at adding user navigation in. This was easy as I had already done similar things in previous examples. I used my flow and response example, where a new bouncing ball was generated every time the user pressed the down arrow on their keyboard, to write code that would increase and decrease the currentCity variable whenever the user pressed the left or right arrow keys. I then used the Spider-Man colouring in example, where I had buttons to change colours, to create buttons that would do the same as the arrow keys on the keyboard.

This worked straight away but I had to set conditions for it to loop once it reached the end of the array (go back to the start after it reaches the end, or to the end from the start if going backwards), otherwise it would crash. This was fairly easy too, I just had to set the currentCity to equal 0 if it went over the length of the cities array, or set it equal to the length of the array if it went under 0.

As I was navigating through the different locations, the thermometer was jumping straight from one value to another, so I thought I might try and make it a little bit nicer. I put in another variable which checked whether the new temperature was greater than or less than the temperature of the previous city and then lowered it or raised it gradually instead of instantly, creating a nice animation effect.

The next thing that I wanted to look at was the clouds. So far, I had only been able to create so many before they would disappear, and I couldn’t get them to move based on the wind speed that I had retrieved. I ended up fixing both of these issues by making the x position of the cloud reset to a new position whenever it hit the width of the canvas, and setting the windSpeed variable before any of the functions so that it was accessible to the cloud function.

Generative System G.png

I now had everything working as I wanted it to apart from the last bit of text left on the screen – the condition. I needed to create if statements that would run animations based on the retrieved condition, and I also needed to create new animations for:

  • Storm clouds.
  • Rain clouds.

I also noticed with my animation that sometimes when changing to a new city for the first time, the graphics would build up on top of each other and look messy until the image loaded properly. I realised that this was because I was loading the images in the draw function and not in my preload function. I moved the bit where it loads the images into the preload function, and created a for loop which stored each one in an array. However, this array was relying on a number value so I had to take the shuffle function off my array of cities in order for the numbers to line up with the images array. Instead of having the cities display in a random order each time, I now made the first displayed city random and then the rest alphabetical.

Generative System H.png

I ended up managing to show rain and lightning in the animation as well. I originally started off trying to display rain in a similar way to the clouds, with different blue ellipses falling all over the screen. I found it hard to replicate because when you clicked into a rainy city, the rain clouds would start rolling in but the rain would start displaying all over the screen, even where the rain clouds hadn’t reached yet. I need some kind of way to make the rain start scrolling in with the clouds and then stay on the screen whilst it is raining and then scroll back out again when you click into a non-rainy city. When playing around with it, I found that placing angled, white strokes all over the screen that display randomly looked more effective and it was easier to implement. I also decided to make the city condition change instantly, rather than trying to make the rain adapt to the new condition scrolling through. I thought that in doing this, the user won’t be given any false impressions about the weather conditions because they will instantly be shown when the button is pressed and they won’t have to wait for the new condition to roll onto the screen. It also allows them to navigate the interface whilst understanding the conditions more quickly.

Generative System I.png

When thinking about how to replicate the lightning during a thunderstorm, I decided to have a look at Open Processing again for inspiration. I found this example, which keeps on drawing a new line to different x positions until it reaches a certain height, creating a line that keeps changing direction as it falls. I thought that this was a very good representation of the way that lightning acts so just like with the sun, I decided to base my animation off of the Open Processing example. This worked effectively, and I found this screenshot in particular very interesting, looking like the lightning is striking a ferry on the harbour:

Generative System J.png

When showing my work to my tutors and peers, I received feedback on how it was an interesting concept (particularly with the animating thermometer), and how it was good to have the API working in there. However, Paris was cloudy with a wind speed of 0 at the time, meaning that the clouds were blocking the sun and not moving themselves, so there was no animation at all to offer to the user (this was the first time that I had come across a situation like this). I asked for feedback on how I could make situations like this more interesting and I was told that it might make it better if more information was shared so that there was more to look at in each city. My aim for this project was to create a visual generation rather than text, hence the removal of all of the text I had in the animation when I was testing it, so we thought that maybe I could show the time and create a dark overlay to show whether it was night time or day time in that city. I also didn’t really want to take too much away from the real factual information that it was giving by making it display something completely random. This may not have been offering much more animation wise, but at least it would offer the user more interesting things to take in and it would mean that it would be acting as a clock as well, rather than just a barometer. I also believed that once I populated it with more cities, it would offer a more interesting experience because the user could keep clicking through the different cities rather than looking at the same four. With only two days left until it was due (in which I had to go to work all day on both of those days), and the blogs due on the same night, I decided to have a go at adding these in as well.

I came across a few difficult situations. Firstly, I was receiving no single time value back with the weather data, only a string that had the date, time and time zone. I wanted to be able to check whether the current time was before or after sunset and sunset in that city and then display a dark overlay if the sun wasn’t up. I found this example on W3 Schools, which takes sections of a string, so I got the section of just the hours and minutes for the current time, sunrise time and sunset time. I then had to convert them to numbers and check whether the current time value was before sunset or after sunrise, and if it was make it draw a dark overlay over the image and behind the cloud.

I decided to try and add a moon in as well, in which I used my sun animation, turning it to white and removing the excess scribble outside of it’s diameter. This created a really effective look except it kept drawing it over and over just like the sun, making the moon constantly move and look unrealistic. After ages of playing around with it, I managed to get it to stop constantly being drawn by removing the random variables from the moon function and placing them in the setup, making them only change when the city changes so that a new moon is generated for each city, but it keeps drawing the same moon whilst it is on the same city. I also added a glow behind it with ellipses that increase in opacity and brightness as they get smaller. I ended up with this cool night time animation:

Generative System K.png

After getting all of the code working properly, I began to populate the generative system with different cities. This was very easy to do because of the way that I set it up. All I had to do was get the WOEID from the website that I had found earlier, place it in the cities array, and then create an image named after that city and place it in the assets folder. I kept doing this and made sure that there was a lot of cities in there so that there was a lot to look at. I also made sure that I included cities with all different weather conditions in order to increase the chances of every aspect of the animation being shown when it is run, this included having tropical cities such as Darwin to increase the chance of there being a thunderstorm included and I wasn’t disappointed:

Generative System L.png

As I added more and more cities, I surprised myself with how interesting it was becoming, being able to constantly navigate through the cities and see all of the different animations. It actually helped me to learn more about the time zones and weather conditions in different cities by being able to navigate through them and compare them so quickly. I found myself at times thinking that things didn’t seem right and maybe something was wrong (even though I felt my code was right), and then I’d Google it to find out it was in fact correct, it was just something I didn’t know about the city. For example, I saw at 7:30pm that the sun was down in Brisbane and Sydney but then when I got to Melbourne it was sunny and I thought “oh no, what’s gone wrong here?”. I Googled it to find that the sun doesn’t set until around 8pm in Melbourne.

Overall I was very impresssed with what I was able to create at the end of the semester, I felt like I had included a lot of the things that I had learnt throughout the progress of this course. Through learning the extra feature in using an API to access data, I felt like I was creating a more generative experience by using real world information to generate data. I had hoped to be able to create something with information like this since I saw the example earlier in the semester that used flight paths to create an animation so I was very happy to be able to do something like this in the end and create something that continually interests even myself.

NOTE THAT I FOUND THAT FOR SOME REASON THE ANIMATION ONLY RUNS FROM A LIVE PREVIEW IN A CODE EDITOR AND NOT FROM THE INDEX.HTML FILE

Tim Dickson – Blog 13

This week I continued to work on my generative system based on what I had set up last week with the weather API. I started off by styling the application to look more like what I had in mind. I found a font which resembled the kind of effect that I wanted for the city name and loaded it in, and I also set up a system that loads the images of the cities in. I used a similar system to the one that I set up when I started making a memory game a few weeks ago, where I created an array full of values and then used them inbetween two other strings to generate the path to the image, meaning that the code for the path was only written once altogether instead of once for each image. I wanted to make the city name’s text to be in uppercase, and I managed to find this example on W3 Schools to help me achieve that. I also added navigational features to the user interface, having two buttons down the bottom of the screen which will allow the user to navigate through the cities backwards or forwards, placed above an overlay on the image. I drew a thermometer to the right of the screen which will be used to show the temperature of each city once I figure out the code to convert the return value into the height of the mercury.

Generative System D.png

In the tutorial, we were shown examples of particle systems and how they are generated. I found this example of fireworks particularly interesting and thought about how I may be able to use something similar in my animation to generate rain if a rainy condition has been returned:

Fireworks.png

 I started to animate my generative system by making clouds that move across the sky. I took inspiration from the array examples that I had used in previous weeks, which involved little circles moving around the screen randomly as the x and y values were constantly changing slightly. I modified this code to create the effect of clouds by creating three larger circles, with two of them being smaller than the main circle, positioned to either side. I made them generate in different greyscale shades, just as clouds do, and I made only their x value change in one direction and their y value remain the same, so that they move sideways across the sky just like real clouds do. I made it generate 250 of them to the left of the canvas and move across, but then once they reached the other side they disappeared. I also wanted the wind speed to be able to control the speed of the clouds, but when I tried to pass the windSpeed variable into the cloud function it didn’t seem to work properly, causing the whole application to crash.
Generative System E.png
It was a good start to the interface though. Now I just need to focus on:
  • Making the clouds continuously generate and flow across the screen
  • Showing the temperature on the thermometer
  • Having the wind speed control the clouds
  • Having rain and thunderstorm animations
  • Displaying a sun that disappears behind the clouds
  • Allowing the user to be able to navigate the interface

Tim Dickson – Blog 12

I wasn’t too sure about how effectively I could make the plane animation that I started on last week meet the requirements of the brief and how well I would be able to carry it out so I started to look for either ideas for my generative system. I looked at the following examples that Liam and Harrison posted in Slack to see if they gave me any inspiration: 

via Ryoji Ikeda via Raven Kwok

I also looked at the examples on the p5.js editor to see if I could find anything that interested me. I found this Interaction: Reach example pretty interesting, where it grabs the ball as it gets near the arm and then throws it away, and thought about similar things that I may be able to do:

Reach A.png Reach B.png Reach C.png
via p5.js Alpha Editor

 

I thought about the possibility of having multiple arms, and multiple balls, I could possibly even create an octopus like creature out of it, but when thinking about adding user interaction and other features, I wasn’t sure where to go with it.

I started going back through my blog for inspiration and found myself looking at the examples that used csvs to generate visual infographics again. It was something that I really wanted to try so I started to attempt to do one. I found this example on the p5.js alpha editor, which loaded earthquake information from an external url into the program so I now had the code to be able to do it, I just needed to be able to find somewhere where I could get information from.

I started looking at surf reports and weather reports to see if there was any APIs that I could use that had lots of information that I could draw into my system and I found one from Magic Seaweed and one from Yahoo Weather. The Magic Seaweed one looked pretty good and the instructions were very informative, however it was only in a beta stage and you had to request access to it, where the Yahoo Weather one was all there and ready to use, so I started to play around with that.

I found out that the Yahoo Weather API required Where On Earth Identifiers (WOEIDs) to load information for different cities, and I found this website which allows you to find all of them. I started off trying to load the information for Sydney, before loading information for a few other cities as well. Just like in the memory game I started to create a couple of weeks ago, I created a request that would load a url based on two strings with a variable inbetween like this, so that the request url only had to be written once instead of for every city:

var url = 'https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%3D' + cityWOEID +'&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=';
weatherForecast = loadJSON(url);

I was able to combine the Yahoo Weather API with the p5.js earthquake JSON example and with some previous JavaScript knowledge, alert the JSON response to determine what values I was able to use. From there, I used the following resources to display the values that I needed:

  • W3 Schools to convert the JSON response into a text string
  • W3 Schools to convert the JSON response into a number
  • W3 Schools to round the number up to so many decimal places
  • Check Your Maths to learn how to convert miles per hour into kilometres per hour
  • Stack Overflow to learn how to remove the quotes that were left in the string

I then displayed all of these values that I needed as text elements in p5.js This is the code and the result that it creates:

/*
* @name Generative System
* @author Tim Dickson
* @description Progress on my second assignment.
*/

// Create the variable that will pull the weather data
var weatherForecast;

// Create an array with the woeid code for selected cities
var cities = [['Sydney', 1105779], ['New York', 2459115], ['Melbourne', 1103816], ['San Francisco', 2487956], ['Brisbane', 1100661], ['London', 44418]];

function preload() {

// Create a number that will randomise which city's information is displayed
var randomNumber = Math.round(random(0, 5));

// Load the data from an external url into the weatherForecast variable
var url = 'https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%3D' + cities[randomNumber][1] +'&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=';
weatherForecast = loadJSON(url);

}

function setup() {

// Set the canvas size
createCanvas(1000, 1000);

// Set the text settings
textAlign(CENTER);
textSize(30);

}

function draw() {

// Draw the background
background(200);

// Get the location, remove the quotes from the string and display it
var location = JSON.stringify(weatherForecast.query.results.channel.location.city);
locationWithoutQuotes = location.replace(/\"/g, "");
text('City: ' + locationWithoutQuotes, 0, 100, width, 50);

// Get the temperature, convert it to celsius, round it up and display it
var temperature = Number(weatherForecast.query.results.channel.item.condition.temp);
var temperatureInCelsius = (temperature - 32) * 5 / 9;
var temperatureRounded = temperatureInCelsius.toFixed(1);
text('Temperature: ' + temperatureRounded + ' degrees', 0, 200, width, 50);

// Get the wind speed, convert it to km/h, round it up and display it
var windSpeed = Number(weatherForecast.query.results.channel.wind.speed);
var kmh = windSpeed * 1.609344;
var kmhRounded = kmh.toFixed(1);
text('Wind Speed: ' + kmhRounded + ' km/h', 0, 300, width, 50);

// Get the wind direction and display it
var windDirection = Number(weatherForecast.query.results.channel.wind.direction);
text('Wind Direction: ' + windDirection + ' degrees', 0, 400, width, 50);

// Get the condition, remove the quotes from the string and display it
var condition = JSON.stringify(weatherForecast.query.results.channel.item.condition.text);
conditionWithoutQuotes = condition.replace(/\"/g, "");
text('Condition: ' + conditionWithoutQuotes, 0, 500, width, 50);

}
Generative System C.png

 

Tim Dickson – Blog 11

In our final Kadenze tutorial, we looked at adding cameras and more to our drawings, this involved looking at some of the things that you can do beyond the p5.js library.

There are a number of addon libraries that come with p5.js that extend its basic abilities. There is a p5.dom (Document Object Model) library which has the ability to create and interact with HTML elements outside of the graphics canvas (it lets you create other elements on your page and do cool things with them). There is also a p5.sound library which as the name suggests, allows you to use sound files within the drawing. These p5.dom and p5.sound libraries need to be referenced in the html file if they aren’t already in there.

A button can be created using the following code:

var button = createButton("label that you want to put on the button");

By creating the button inside a variable named button, it allows us to reference it throughout the code and do other things with it such as setting its position:

button.position(x position, y position);

The createCanvas method that we use in every drawing is also a create method, so we can also use a pointer to position it as well.

var canvas = createCanvas(width, height);

canvas.position(x position, y position);

Another thing that I noticed in the tutorial that I hadn’t seen before was the use of colour modes:

colorMode(HSB);

I looked it up and found out that HSB stands for hue, saturation, and brightness, and from what I saw in the tutorial, it looks like it offers a brighter variety of colours.

To trigger an event when the buttons are pressed, we need to write the following code:

button.mousePressed(function that you want to call);

Other create methods that we can use include createP which creates a paragraph of text on the page, and createInput which creates a box that can be used to give text input into your program. An example of this would be:

var input = createInput();

Unlike the others, createInput doesn’t take any arguments inside its parentheses. We can use .value to get the value of an input box.

createSlider is another create method that we can use, which creates a slider that can be used to manipulate elements of the sketch. It takes three arguments: the minimum value, the maximum value and the starting value:

var slider = createSlider(minimum value, maximum value, starting value);

Just like with the input box, we can use .value to get the value of a slider.

Another useful tip that I picked up in this tutorial was that .webm as a video format works particularly well across a lot of different browsers. We can include videos in our drawings by using the code:

var video = createVideo("path to the video");

We can then use video.loop to play the video repetitively and video.pause to pause the video.

To change the label of a button, we can use the following code:

button.html("new string");

To draw the frames of a video on the canvas, we can use:

image(video, x, y);

Another interesting thing that I noticed was the ability to use filters on images, such as:

filter('INVERT');

We can then use the following code to hide the video and only show the frames being drawn as images on the canvas:

video.hide();

Another create method that we can use is createCapture, which accesses the webcam on your computer and creates a html element that displays the video feed from it. Just like with an image object, we can also access the pixels of our capture object like this:

capture.loadPixels();

In addition to capturing video, we can also capture our microphone input and work with that too:

var mic = p5.AudioIn();

mic.start();

mic.getLevel();

There is a whole lot more that you can do with p5.dom and p5.sound. In addition to these libraries, there are many other user-contributed libraries that help you extend into other domains such as games, speech, etc.

I decided to code the example from the webcam and microphone tutorial to get a better understanding of how it works. This code only works when run locally though and not in the p5.js alpha editor:

/*
* @name Webcam and Microphone
* @author Tim Dickson
* @description A drawing that uses the webcam and microphone inputs to draw ellipses of different sizes and shades.
*/

// Set the variables for the webcam and microphone
var capture;
var mic;

function setup() {

// Set the canvas size
createCanvas(710, 400);

// Set the capture variable to equal the webcam input
capture = createCapture();
capture.hide();

// Set the mic variable to equal the microphone input
mic = new p5.AudioIn();
mic.start();

// Set how the ellipses will be displayed
noStroke();
fill(0);

}

function draw() {

// Set the background colour to white
background(255);

// Load the pixels from the webcam input
capture.loadPixels();

// Set the size of the ellipses based on the volume of the microphone input
var stepSize = round(map(mic.getLevel(), 0, 0.5, 10, 50));

// Create a loop that places the ellipses across the screen vertically and horizontally
for (var y = 0; y < capture.height; y += stepSize) {
for (var x = 0; x < capture.width; x += stepSize) {

// Set the darkness of the ellipse based on the darkness of the pixels from the webcam input
var i = y * capture.width + x;
var darkness = (255 - capture.pixels[i * 4]) / 255;

// Set the radius for the ellipses based on the darkness and volume level
var radius = stepSize * darkness;

// Draw the ellipses
ellipse(x, y, radius, radius);

}
}

}
Webcam and Microphone.png

In class, we looked at a flocking example where ellipses would move around in groups, just like schools of fish. After seeing this, I didn’t think that I would be able to offer enough out of a memory game so I started to think of ways that I could do something similar.

Flocking.png

 An example I thought of was Roulette planes, which fly in different formations in the sky. I could possibly have an animation which randomly showed the planes flying in different formations across the screen and the user could interact with them by making them do things, giving them control over the animation. I wasn’t too sure on how it would work yet, but it was just an idea that came to mind for now.

via Wikipedia

 I started to code something to see if it got me anywhere and I came up with the following animation, which sees the planes continually flying in formation from left to right across the screen with a cloud travelling in the same direction at a different speed. It showed that I was able to load everything that I needed into it, it was just a matter of figuring out what I would be able to do with it:

/*
* @name Generative System
* @author Tim Dickson
* @description Progress on my second assignment.
*/

// Create variables for the plane and cloud positions
var planePosition = 0;
var cloudPosition = 0;

function preload() {

// Load the images for the planes and the clouds
plane = loadImage("assets/plane.png");
// @source https://pixabay.com/en/plane-propeller-old-flight-biplane-146181/
cloud = loadImage("assets/cloud.png");
// @source http://www.freepngimg.com/png/5109-cloud-png-image

}

function setup() {

// Set the canvas width and height to fill the window
createCanvas(windowWidth, windowHeight);

}

function draw() {

// Create a sky gradient background
for (lineHeight = 0, greenColour = 100; lineHeight < height; lineHeight ++, greenColour += 0.1) {
stroke(0, greenColour, 255);
line(0, lineHeight, width, lineHeight);
}

// Make the planes move from left to right and reset them if they go outside of the window
if (planePosition <= width + 600) {
planePosition += 5;
} else if (planePosition > width + 600) {
planePosition = -200;
}

// Draw the cloud and make it move across the window from left to right
image(cloud, cloudPosition, 200, cloud.width / 3, cloud.height / 3);
cloudPosition += 0.5;

// Draw the planes
drawPlanes();

}

function drawPlanes() {

// Make the planes jitter slightly to look more realistic
this.jitter = random(-0.5, 0.5);

// Draw the planes in formation and make them follow the height of the mouse position
image(plane, planePosition, pmouseY);
image(plane, planePosition + 75, pmouseY - 100 + jitter, plane.width / 2, plane.height / 2);
image(plane, planePosition + 100, pmouseY - 200 + jitter, plane.width / 3, plane.height / 3);
image(plane, planePosition - 250, pmouseY - 70 + jitter, plane.width / 1.5, plane.height / 1.5);
image(plane, planePosition - 200, pmouseY - 175 + jitter, plane.width / 2.5, plane.height / 2.5);
image(plane, planePosition - 450, pmouseY - 100 + jitter, plane.width / 2, plane.height / 2);

}
Generative System B.png

Tim Dickson – Blog 10

This week’s Kadenze tutorial focused on synthesising ideas from the entire course to make a simple game from them. This was interesting because games are a great way to explore interactive potentials, and they are also a new way to tell stories.

This game that we looked at involved:

  • Objects to encapsulate the ideas of each one of the following objects
  • Arrays to make an endless amount of things to catch
  • Simple variables to keep score
  • A program with a state that the user can move between 

It started off by looking at creating objects which fall from the ceiling, with some sort of paddle or basket to catch them down below, and the user getting a point each time that they catch one. With the objects falling from the sky, it used an object in the code that encapsulated its position and how quickly it is moving. It expanded on this by using arrays to make a number of these falling objects and then they added collision detection to create some sort of action when they bump.

It was interesting to see how they incorporated the function into the code by adding the following functions inside the draw function to update and render the ball:

myball.update();

myball.render();

I also learned that you could use .init to set the initial function of an object:

this.init = function() {

Set initial function here

}

This allows this.init(); to be called later on.

 

Some important points that I took note of in the class this week were that:

 

  • Capital letters are used to denote the name of a class, lower case letters are then used to denote an instant of that class
  • The following code can be used to make a number random 5% of the time: (random(0, 100) < 5);
  •  Using \n within a string creates a new line, I have seen this used before in programs such as Balsamiq Mockups to create new lines within a text label so it is a familiar function for me

This week I also began to play around with ideas for my generative system assignment. Following on from my idea of a memory game that I thought of last week, I began to try and create it. The main things that I managed to get working were:

  • Creating an array that held the image names and then getting the values out of this array and placing them within two strings to load the image so that all of the images could be loaded from one line of code
  • Using a for loop inside a for loop to spread the images out across the canvas horizontally and vertically.

I used two images from earlier (that I used in my type story example a few weeks ago) to test the application and this is the code that I came up with and the result that it produced:

/*
* @name Generative System
* @author Tim Dickson
* @description Progress on my second assignment.
*/

// Create an array with the images that will be used
var images = ["transformerRobot", "transformerCar"];

function setup() {

// Set the canvas size to fill the size of the window with a black background
createCanvas(windowWidth, windowHeight);
background(0);

}

function draw() {

// Draw boxes across the screen width and height
newBox();

}

function newBox() {

// Set the boxes to be white with no outline
fill(255);
noStroke();

// Draw boxes horizontally and vertically
for (boxesWidth = 10; boxesWidth < windowWidth; boxesWidth += ((windowWidth - 70) / 6) + 10) {
for (boxesHeight = 10; boxesHeight < windowHeight; boxesHeight += ((windowHeight - 60) / 5) + 10) {

// Create a random number to decide which image is shown in the box
var shuffle = round(random(0, 1));

// Draw the box
rect(boxesWidth, boxesHeight, (windowWidth - 70) / 6 , (windowHeight - 60) / 5)

// Place an image in the box
boxImage = createImg("assets/"+images[shuffle]+".jpg");
boxImage.hide();

// Set the image width and height
imageWidth = (windowWidth - 70) / 6;
imageHeight = ((windowHeight - 60) / 5) - 20;
image(boxImage, (boxesWidth + (imageWidth / 2))-(imageHeight / 2) , boxesHeight + 10, imageHeight, imageHeight);

}
}

}
Generative System A.png

Tim Dickson – Blog 9

This week was focused on data and visualisation, a topic that I found very interesting. Our world produces a tremendous amount of data, making sense of this data is not an easy task. Visualisation analyses and represents data as a visual form to help us make better conclusions and get a better understanding of large data sets. Arrays let us access and manipulate large amounts of data. They hold a list of values, rather than just a single quantity.

An array is created with the following code:

var arrayName = [];

You can refer to each slot in an array by using its index, for example arrayName[0] would refer to the first item in an array.

Computers can’t generate truly random numbers, there’s always an algorithm behind the scenes determining when numbers should appear.

However, the numbers that they generate are still more random than a what a human would be able to generate, an interesting quote from this tutorial was that “if computers are bad at generating random numbers, then humans are terrible at it”

I also learned that text files could be loaded into the preload function as strings:

loadStrings("numbers.txt");

Another useful function that I found out about was the round function:

round();

I had previously been using Math.floor();, which I found on W3 Schools.

It was very interesting to see the comparison between human behaviour and computer behaviour and how humans tend to avoid numbers around 50 cause they don’t seem random enough, whereas computers will pick numbers wherever.

The examples used to show data visualisation were really engaging – Casey’s demonstrations of the guy that created graphics of the life stats of his father:

Feltron Annual Report.png
via Feltron

 

And the coding used to networj and connect different places together were very cool, combining the act of printing with the act of coding. I really liked the aeroplane flight path animation in particular:

Visualising Flightpaths.png
via Kadenze

 

I would really love to represent something similar in my assignment and create something from a real time csv/json. Flight patterns reveal something unexpected, we know they are above us all of the time but don’t quite know the extent until we use coding to visualise it. 

The generative text animation based on speech was also cool as well as the cities latitude and longitude being mapped to the size of the square in the animation.

With visualisation, you start with a bunch of data, text, or numbers and through code you are able to transform that into a really compelling image/visualisation on the screen.

I think that using a csv file to generate information in my generative system assignment could make it really interesting, so I started looking around for csvs. I came across some such as this one, which contains a list of information about different Australian towns.

 

I also looked elsewhere for information and thought about possibly creating an interesting memory game. This would be like a standard game of memory where the user has to try and match two of the same images together, but it could be more interactive and generative by:

  • Having different categories that they user could navigate in order to create their own story
  • Having lots of different animations as the user uses the program to make the concept more interesting and engaging for the user

I expect my ideas to continue developing and changing over the next couple of weeks until I end up with a solution that I am truly happy with that meets all of the requirements of the brief.

Tim Dickson – Blog 8

This week we looked at objects and modularity, as well as taking related variables and functions and bringing them together to create multiple copies of these objects.

These can have variable fields or properties and we call functions methods. We can define an object using a special function called a constructor.

Here is an example where a Bug class is created with two methods inside it which draw and update the bug:

var fly;

var sam;

 

function setup() {

  createCanvas(900, 600);

  fly = new Bug(width/2, height/2);

  same = new Bug(100, 100);

}

 

 

function draw() {

  background(255);

  fly.draw();

  fly.update();

  sam.draw();

  sam.update();

}

 

function Bug(startX, startY) {

  this.x = startX;

  this.y = startY;

  this.diameter = random(10, 100);

  this.speed = random(2, 10);

 

  this.draw = function() {

    fill(0);

    noStroke();

    ellipse(this.x, this.y, this.diameter, this.diamter);

  }

 

  this.update = function() {

    this.x += random(-this.speed, this.speed);

    this.y += random(-this.speed, this.speed);

  }

}

The class contains the bug’s properties and the keyword ‘this’ refers to future instances of this object. This lets you know that the methods and properties that you are referring to are local to this object. Just like with any other function, you can also pass parameters into an object.

 

 

  • Variables define the nouns
  • Methods define the functionality of the object 

 

I found it very interesting to discuss Don Norman’s Design of Everyday Things in the class this week as well. It is a book that I have just purchased and started to read, and I hope to use my learnings from both the course and book together as the semester progresses.

The most important takings from the class were that:

  • Classes start with a capital letter
  • A method uses this operator: this.move = function() {
  • this = nowhere else.. just here

We looked at modifying the code for the Objects: Array example, this is what I came up with, different coloured falling balls that keep bouncing until they stop and then drop out of the canvas:

/*
* @name Modified Objects Array Example
* @author Tim Dickson
* @description A modified version of the p5.js Objects Array example. It features objects of different colours that Bounce rather than Jitter.
*/

// Declare the objects, whether they are falling or not, and their colours
var ball = [];
var falling = [];
var colours = [[168, 114, 221], [209, 154, 102], [68, 158, 176], [75, 171, 239], [218, 108, 117], [229, 187, 102]];

function setup() {

// Set the canvas size
createCanvas(1000, 1000);

// Create the balls
for (i = 0; i < 100; i++) {
ball[i] = new Bounce();
}

}

function draw() {

// Set the background colour
background(40, 44, 52);

// Display the balls
for (i = 0; i < 100; i++) {
ball[i].fall();
ball[i].display();
}

}

// Create a class for Bounce
function Bounce() {

// Set the position, size, speed, and colour
this.x = random(width);
this.bounceBack = random(height);
this.y = this.bounceBack;
this.diameter = random(10, 30);
this.speed = 3;
this.falling = true;
this.colour = Math.floor(random(0, 6));

// Create a function to make the balls fall and bounce
this.fall = function() {
if (this.falling == true) {
this.y += this.speed;
this.speed = this.y * 0.005;
}
if (this.y >= height - this.diameter / 2) {
this.falling = false;
this.bounceBack += 20;
}
if (this.y <= this.bounceBack - this.diameter / 2) {
this.falling = true;
}
if (this.falling == false) {
this.y -= this.speed;
this.speed = this.y * 0.005;
}
};

// Create a function that displays the balls in their current position
this.display = function() {
fill(colours[this.colour]);
ellipse(this.x, this.y, this.diameter, this.diameter);
}

};
Modified Objects Array Example.png

Tim Dickson – Blog 7

This week we looked at building new code modules.

Functions encapsulate related code that performs a specific behaviour. They are a good way to lower the amount of code and repetitiveness.

They are also easy to read and easy to reuse.

A function can be created by using the following code:

function name() {

 

}

This is just like how we use the draw and setup functions. 

The name has to be made from letters, numbers or underscores, it should always start with a letter and case does matter.

Inside the curly brackets, we define the body of a function.

The body of a function is executed whenever we call that function. To call a function, we use: 

functionName();

To pass values into a function, they go inside the parentheses: 

function functionName(values) {


}

Here is an example of values being passed into a function, where the values we place inside the parentheses when we call the function are used to replicate the values inside the parentheses when we define the function:

name(300, height / 2);

function name(x, y) {

  ellipse(x, y, 300, 300);

}

By doing this, we can put out of our mind how the target function works and focus on using it. This lowers the amount that you need to think through when thinking about how your program is working, you can put them to the side and trust that they will do what they need to do.

Some other things that we covered were that random values can be defined by using: 

value = random(min value, max value);

And the draw function can run once, instead of 60 times per second, by using:

noLoop();

Functions are able to do maths and return values, except for the rect(); and ellipse(); functions which don’t return values.

Values of 0 and 100 in random functions make them map to percentages.

Some interesting examples shown of where code modules have been used were for the panel building recursion on buildings, where parameters where used to reduce panel costs and heat efficiency, the butterfly wings that were generated with code modules, and the nervous system 3d jewellery design.

 

Another really interesting example was the Kadenze example of recursion trees, where new trees are generated each time that the program is run by branching different curves off of each other, a more complex example of recursion code.

In class we talked about functions and functions inside functions (recursive functions), also how programs are measured by how expensive they are to a computer. We talked about declaring variables globally so that everything can access it, whereas if we declare a variable locally no other functions would be able to access it. We used the objects example in the p5.js alpha editor to hack the Jitter code and see what we were able to come up with. I changed the colours of my Jitter objects to be random grayscale colours that continually change and flash, and I placed them in an array so that many of them were placed around the canvas:

 

/*
* @name Modified Objects Example
* @author Tim Dickson
* @description A modified version of the p5.js Objects example. It includes multiple objects that flash in different shades.
*/

// Declare the objects
var bug = [];

// Set the list of colours available
var colour = [[250, 250, 250], [200, 200, 200], [150, 150, 150], [100, 100, 100]];

function setup() {

// Set the canvas size
createCanvas(1000, 1000);

// Create the objects
for (i = 0; i < 200; i++) {
bug[i] = new Jitter();
}

}

function draw() {

// Set the background colour
background(50, 89, 100);

// Shuffle the colours as the objects display
for (i = 0; i < 200; i++) {
colourChanger = Math.floor(random(0, 4));
fill(colour[colourChanger]);
stroke(colour[colourChanger]);
bug[i].move();
bug[i].display();
}

}

// Create a class for Jitter
function Jitter() {

// Set the position, size, and speed
this.x = random(width);
this.y = random(height);
this.diameter = random(10, 30);
this.speed = 1;

// Make the objects move
this.move = function() {
this.x += random(-this.speed, this.speed);
this.y += random(-this.speed, this.speed);
};

// Display the objects
this.display = function() {
ellipse(this.x, this.y, this.diameter, this.diameter);
}

};
Modified Objects Example.png

Tim Dickson – Blog 6

This week was focused on motion, and moving and choreographing shapes, which I found very interesting.

We looked at smoothing animation and creating motion using code, and we saw examples of faster motion looking more jerky.

Here is an example of using easing to smooth motion: 

line(x, 0, x, height);

var easing = 0.5;

var diff = mouseX - x;

x += diff * easing;

Motion is a great way to add simple animations to a program, it creates more enhancement than just a straight linear program.

Transformations also allow us to alter the plane so that we can draw things in a new way.

Translate redefines the origin to a different point in the grid.

For example we can use translate to remove repetition and duplication by converting this:

line(mouseX - 50, mouseY - 50, mouseX + 50, mouseY + 50);

line(mouseX + 50, mouseY - 50, mouseX - 50, mouseY + 50);

To this:

translate(mouseX, mouseY);

line(-50, -50, 50, 50);

line(50, -50, -50, 50);

We can also use the following single argument to define how much you want to rotate an object, it takes values in radians between 0 and 2 pi:

rotate();

We can also use the following code to translate between degrees and radians:

radians();

We can make an object rotate over time by setting rotate to a variable and incrementing it.

We can use the following code to scale our drawing up to however many times larger:

scale();

The push and pop functions bracket transformations, they temporarily execute code and then remove the implementations to go back to the way that the transformations were before. They look like this:

push();

// transformation code

pop();

// back to normal

We can also use sin and cos functions to get smooth motion.

The sin function, when passed a value for an angle, gives you the sin of that angle. For example:

var angle = 0;

var offset = 150;

var scalar = 100;

var speed = 0.025;

 

function setup() {

  createCanvas(900, 600);

  fill(0);

}

 

function draw() {

  background(255);

  var y1 = offset + sin(angle) * scalar;

  var y2 = offset + sin(angle + 0.4) * scalar;

  var y3 = offset + sin(angle + 0.8) * scalar;

  

  ellipse(50, y1, 100, 100);

  ellipse(150, y2, 100, 100);

  ellipse(250, y3, 100, 100);

  angle += speed;

}

 

We can also create a timer using the following function, which gives us the number of milliseconds gone by since the program began running:

millis();

 

Here is an example of the millis(); function in use:

var timer = 20;

var bgColor = 0;

var nextTime = 500;

 

function setup() {

  createCanvas(900, 600);

  fill(0);

}

 

function draw() {

  background(bgColor);

  if (millis() > nextTime) {

  bgColor += 20;

    nextTime = millis() + timer;

  }

  

}

 

I finally gained some inspiration for my non-linear animation from one of the Kadenze examples, which showed lines moving in unison and bouncing around off certain parts of the canvas. I found this really interesting and decided to try and replicate something similar in my animation:

Choreographing Shapes.png
via Kadenze

 

I created an animation which has four different coloured lines that travel together, bouncing off invisible walls, using an array in which the values are implemented simultaneously. I found that it got messy though when it kept drawing over the top of itself:

 

Non-Linear Animation A.png Non-Linear Animation B.png

Some changes that I wanted to make where to:

  • Put a skip in so that it would make it to the bottom right corner (it would skip the invisible walls occasionally and hit the actual walls)
  • Randomise the direction at the start to make it even more non linear
  • Put a white background over the top so that it didn’t get so messy
  • Add more colours to again make it even more non-linear
Non-Linear Animation C.png Non-Linear Animation D.png

I came up with the above result, which shows only sections at a time and creates a really interesting flashing effect of them all moving around together, you can also see that they are using more colours in random orders. When trying to make them move more smoothly and from multiple directions, I got the code to work properly as you can see below, but sometimes the lines would run off on their own and I couldn’t figure out why, so I stuck with the above animation:

Non-Linear Animation E.png Non-Linear Animation F.png
Non-Linear Animation G.png Non-Linear Animation H.png

 

 

Tim Dickson – Blog 5

This week we looked at non-linear narratives.

Non-linear is when you run something with the use of random variables, meaning that it doesn’t always do the same thing.

Non-linear narratives are types of stories that doesn’t follow directly from a to b, they remind me of the Goosebump type books.

Zork was a really interesting example of a non-linear narrative, which uses only text commands to create a story:

via Mental Floss

 

Non-linear narratives create an strong desire for users to participate in them.

Another example of a non-linear narrative program is Twine, which uses a storyboard based flowchart to setup the possible story:

via Twine

I found the Alice In Wonderland example in the Kadenze tutorial really cool and decided to try and create my own non-linear narrative, based on a transformer transforming. Whilst it isn’t a full story it shows the same features as what the Alice In Wonderland example was doing. Something really handy that I found whilst doing this was this website which tells you all of the keycodes for different keys when you are coding their response:

http://keycode.info/

 

I created a program that transforms a transformer from robot to car and back when the user types transform and presses enter. You can see the code and resulting animation below, or view my work in the alpha editor here.

/*
Name: Transforming Transformer
Author: Tim Dickson
*/

function preload() {

// Load required images and sounds
// transformingSound = loadSound("assets/transformer.mp3");
// Sound source: http://www.soundboard.com/sb/sound/85855
car = createImg("https://designprogrammingblog.files.wordpress.com/2017/09/car.jpg");
car.hide();
transformer = createImg("https://designprogrammingblog.files.wordpress.com/2017/09/transformer.jpg");
transformer.hide();
// Image source: https://static.comicvine.com/uploads/original/11116/111163466/4437380-9405503646-Bumbl.jpg

}

// Create variables for state and typed
var state = 0;
var typed = '';

function setup() {

// Setup the program
createCanvas(647,750);
frameRate(2);
textAlign(CENTER);

}

function draw() {

// Display image based on state
if (state == 0) {
background(255);
image(transformer, 0, 0);
} else {
background(255);
image(car, (width - 421) / 2, 587 - 257);
}

// Create an input box with an instruction
noStroke();
fill(240);
rect(100, 630, width - 200, 50);
fill(0);
textSize(30);
text(typed, 0, 587 + 50, width, 50);
textSize(12);
text("Type TRANSFORM and press ENTER", 0, 700, width, 50);

}

function keyPressed() {

// Make sure that keys are alphabetical
if (keyCode >= 65 && keyCode <= 90) {
typed += key;
}

// Take action if TRANSFORM is typed
if (keyCode == ENTER && typed == 'TRANSFORM' && state == 1) {
// transformingSound.play();
typed = '';
state = 0;
}

// Take action if TRANSFORM is typed again
if (keyCode == ENTER && typed == 'TRANSFORM' && state == 0) {
// transformingSound.play();
typed = '';
state = 1;
}

// Delete the text
if (keyCode == BACKSPACE) {
typed = '';
}

}

Transforming Transformer A.png

Transforming Transformer B

Tim Dickson – Blog 4

Our learning this week was focused on media and the loading and displaying of images, shapes, and fonts.

I learned that p5.js is compatible with the following image and sound file types:

  • .jpegs
  • .gifs
  • .pngs
  • .svgs
  • .mp3s
  • .oggs

p5.js runs asynchronously, which means that the program continues to run while certain processes carry on in the background. When we are loading these media files, as well as fonts, we need to make sure that the data is available to the program before we try and access it. We can do this by using the preload function.

var img;
var sound;
var font;

function preload() {
img = loadImage("path");
sound = loadSound("path");
font = loadFont("path");
}

Images are placed in the drawing using the following constraints:

image(name of image variable, upper left x position, upper left y position, width, height);

The aspect ratio of an image can be set using:

var aspect = img.height / img.width;

The size of an image can follow the position of the mouse by using the following code:

var imageWidth = mouseX;

var imageHeight = imageWidth * aspect;

Text can also be loaded into the drawing by using:

textFont(“path to the font”);

The text size can be set through:

textSize(22);

The text can then be drawn by using:

text(“string contains the letters to draw”, x position, y position, size wrap width, size wrap height);

The text is positioned by its lower left hand corner, or upper left hand corner if it is size wrapped. We can use web fonts for online use, in which Google Fonts is a good source. It is best practice to load the fonts in the index.html under the title tag, to make sure that they are available by the time that you want to use it.

A sound can be played by using:

sound.play();

And the following code will set the volume of the sound:

sound.setVolume();

This value has to equal a value between 0 and 1.

The sound can be looped through:

sound.loop();

I found this example of a clock which uses rotating video snippets really engaging:

It reinvents analogue passage of time through circular images capturing video slices. The centre ring replicates hours, the middle ring replicates minutes, and the outer ring replicates seconds.

I also found the examples of the sky, television tuner, and busy city street with the slit scanning technique used really cool.

When you start loading images, videos, fonts and geometry into your program, new possibles for exploration begin to come out.

The slit scan process involves transforming frames of video into a single image, and it can often reveal interesting patterns in the source video.

The following code can be used to constrain:

constrain(constraint, startrange, endrange);

Slit scanning draws column of pixels based on the position of an image over a line, and it increments it across.

 

In class, we talked about how to represent structures algorithmically.

Mondrian art involves tessellating simple structures across a strong opposition of blank space, using hard thick black lines, and colour representations in-between.

It is interesting when you think about how to represent this stuff algorithmically.

The more complex, chaotic artworks offer overall greater visual appeal.

They tend to be moving from original plotter based artworks forward to the modern day of creating art and are still using the exact same simple principles/processes.

It makes you think about why are we still using the exact same technologies as we were in the 70s to create interesting artworks?

We can use design programming for data visualisation, infographic purposes, and also be to create works of art.

Examples include Michael Snitchers evolving logo, which used computer based processes to generate a dynamic logo to represent a company that was invovled with molecular cell biology and genetics, represent closely to evolution.

I really liked this example and thought it was a very clever use of design programming to represent evolution inspired art to create a logo which was genetically evolved. Below are some examples of the Max Planck Institute logo:

via Michael Schmitz

It shows different iterations of the logo which are changed over time, just like real world evolution. It still had mediacy and tangible context with similar shape and colours.

Todays task: how we would be able to create a simple representation like Michael Noll was able to and to begin thinking about how to use sound/video. We should look at creating something that is valid inside a shape, but not outside of it.

A good source of programming help is through W3 Schools.

p5.js is its own body of work.

I created this example using image and sound of a random Sydney Harbour Bridge animation which flashes random sections of the image inside the shape whilst making a sound. You can view the code I wrote and image of the animation below, or view my full work here.

/*
Name: Sydney Harbour Bridge Random Pixel Grab
Author: Tim Dickson
*/

var imgSydneyHarbourBridge;

function preload() {

imgSydneyHarbourBridge = loadImage("https://instagram.fcbr1-1.fna.fbcdn.net/t51.2885-15/e35/20759747_109567579725154_4288487079408566272_n.jpg");
//boopSound = loadSound("http://www.downloadfreesound.com/wp-content/uploads/2013/08/Beep11.wav");

}


function setup() {

createCanvas(999,999);
frameRate(2);

}

function draw() {

for (i = 0; i < 1; i ++) {

background(imgSydneyHarbourBridge);

// Add a circle mask over the image
circleMask = createImg("https://designprogrammingblog.files.wordpress.com/2017/08/circle-cutout.png");
image(circleMask, 0, 0);

// Set random variables for the x and y positions as well as the size
var x = random(1000);
var y = random(1000);
var size = random (50, 250);

// Copy pixels from the image and display them
copy(imgSydneyHarbourBridge, x, y, size, size, x, y, size, size);
stroke(255);
noFill();
rect(x, y, size, size);
//boopSound.play();

}

image(circleMask, 0, 0);

}
Sydney Harbour Bridge Random Pixel Grab.png

Tim Dickson – Blog 3

Flow and response was what we learned about in this week’s Kadenze tutorial. We already know that the setup function is run once at the beginning and is a good place to initially set values and variables. We also know that the draw function is where the magic happens, although we have only touched on static artwork so far. The draw function is run 60 times a second, meaning that if we were to change what we put in there we can start creating some exciting animations.

We learnt some new built in variables that will help us to make our code responsive:

  • mouseX and mouseY recognise the position of where the mouse is.
  • pmouseX and pmouseY populates the mouse position from the last time that the draw function was executed.
  • mouseIsPressed checks to see whether the mouse is pressed or not.

We are able to make use of these variables by putting them in an if statement. An if statement looks like this:

if (test) {
statements
}

The test condition compares whether one value is equal to another and executes the statements inside the parentheses whilst the condition is being met. An important point that was noted here was that if we want one value to be equal to another value for the statements to run we should use to equals symbols instead of one. This shows that we are comparing two values and not setting the values to equal each other.

When I tried to follow along with the tutorial and run the sample if statement it wasn’t functioning as expected, it was running the statement the whole time even when the condition wasn’t being met. Having some previous experience with JavaScript, I tried adding an else statement onto the end of my if statement to tell it to behave as normal if the condition wasn’t being met and this fixed the problem.

The tutorial then went on to discuss else statements afterwards, which define what happens if anything in the if statement isn’t true. Else statements are added onto an if statement like this:

if (test) {
statements
} else {
statements
}

Something that I noticed whilst experimenting with the code is that having a background stops you from being able to draw on the canvas, just as if it covers the canvas and leaves nothing for you to draw on.

Another thing that we learnt about was the map feature, which looks like this:

map(input value, minimum possible value, maximum possible value, start of range, end of range);

We can use this to do things like change a colour as the mouse moves across the screen. This is done by setting the input value to mouseX, the minimum possible value to 0, the maximum possible value to width, the start of the range to 0 and the end of the range to 255. This sets the value to cover the width of the canvas (0 to width) and the range to cover the range of colours (0 to 255) depending on where the mouse is horizontally. I used this to create a brush that changes from blue to pink and creates a nice gradient as you draw across the screen, you can see an example of this in the Spider-Man project that I made further down.

We also learnt about another new thing in the distance feature, which looks like this:

dist(x1, y1, x2, y2);

Just like a line, the distance command takes four x/y arguments but rather than drawing a line between them it returns the distance between them. This can be handy when we are creating things like buttons. For example we can put a circle in the centre of the screen with a radius of 50 and check to see whether the mouse position is within 50 from the centre of the screen to know that the mouse is over the circle. We can then use a double ampersand to check if two conditions are met in the if statement: whether the distance is less than 50 and whether the mouse is pressed. We can use this to execute a change if both conditions are met like this:

ellipse(width / 2, height / 2, 100, 100);
var distance = dist(width / 2, height / 2, mouseX, mouseY);
if (distance < 50 && mouseIsPressed) {
statements
} else {
statements
}

We aren’t only limited to using the mouse to trigger events, we can also determine whether keys on the keyboard are being pressed. We also aren’t only limited to one if statement either, we can use an else if statement to check if another condition is being met instead. This example shows a circle that will move in the direction of the arrow that is pressed on the keyboard:

ellipse(circleX, circleY, 100, 100);
if (keyIsPressed) {
if (keyCode == UP_ARROW) {
circleY -= 5;
} else if (keyCode == DOWN_ARROW) {
circleY += 5;
} else if (keyCode == LEFT_ARROW) {
circleX -= 5;
} else if (keyCode == RIGHT_ARROW) {
circleX += 5;
}
}

Another type of function that we can take advantage of in p5.js is the mousePressed function. It is written just like the setup and draw functions but it is only executed once when the mouse is pressed, rather than 60 times a second. We can also use exclamation marks or “bangs” to set values to be the opposite of what they already are or check whether they are not equal to a certain value. For example, this would set the background colour to blue and then it would change to white when the mouse is pressed, note that it would still be white after the mouse is released because it is relying on a value rather than the mouseIsPressed variable:

var backgroundColour = true;
function draw() {
if (backgroundColour == true) {
background(0, 0, 255);
} else {
background(255);
}
}
function mousePressed() {
if (mouseIsPressed == true) {
backgroundColour = !backgroundColour;
}
}

It was interesting to see Kid Pix being discussed as an example of a program that uses these simple commands as it was a program that I used when I was young. It was also fascinating to see where we have come from Kid Pix, we’re now able to use cameras to draw on on live images using touch screens and then share our work via social networks. I agree that software should be made extremely easy to use, with no manual being needed and with program features explaining themselves through use. All tasks should be able to be performed in the most straight forward, simplest way and the program should go out of its way to meet user needs.

I was inspired by this to go and create my own painting application. I knew that I could do it using the features that I had just learnt such as:

  • Using mouse presses to draw shapes on a canvas.
  • Using key presses to adjust brush sizes.
  • Using buttons to change the colour of the stroke.
  • Using the map command to create gradients based on the mouse position.

I came across an issue where I wanted to use certain keys to change the brush size but couldn’t find the keycodes anywhere to use them so I inputted some text that was equal to a variable and made the variable equal to the key that was pressed so I was able to find out that the keycodes for the [ and ] keys were equal to 219 and 221.

I used the reference library to find out how to embed an image in p5.js so that I could find a transparent outline and effectively create a colouring in application for kids.

https://giphy.com/embed/8zYunr3Hg8XPq

via GIPHY

I also used the reference library to find out how to place text in my program to create an instruction for the user. Below is the code that I wrote and the resulting functionality, have a go of it yourself here.

/*
* @name Spider-Man
* @author Tim Dickson
* @description A colouring in application that uses mouse presses to draw shapes on a canvas, key presses to adjust the brush size, buttons to change the colour of the stroke, and the map command to create gradients based on the mouse position.
*/

// Set the variables to be used later on
var spiderManOutline;
var redFill = 111;
var greenFill = 0;
var blueFill = 0;
var brushSize = 30;

function setup() {

// Set the canvas size
createCanvas(800, 1200);

}

function draw() {

// Add Spider-Man's outline
spiderManOutline = createImg("assets/spiderManOutline.png");
// @source http://pre04.deviantart.net/6981/th/pre/f/2012/223/7/3/spiderman_line_art_1_by_loona_cry-d5aro8x.png
spiderManOutline.hide();
image(spiderManOutline, 0, 180);

// Add a section at the top for instructions and colour selection
fill(250);
noStroke();
rect(0, 0, width, 160);
fill(0);
textSize(16);
textAlign(CENTER);
text("Select a colour to paint with and use the [ ] keys to adjust the brush size", width / 2, 40);
stroke(0);
fill(0, 0, 255);
ellipse(width / 2 - 180, 100, brushSize, brushSize);
fill(247, 10, 38);
ellipse(width / 2 - 90, 100, brushSize, brushSize);
fill(2, 98, 159);
ellipse(width / 2, 100, brushSize, brushSize);
fill(255);
ellipse(width / 2 + 90, 100, brushSize, brushSize);
fill(0);
ellipse(width / 2 + 180, 100, brushSize, brushSize);

// Set where the distances are measuring for the colour buttons
var backgroundColour = dist(220, 100, mouseX, mouseY);
var redColour = dist(310, 100, mouseX, mouseY);
var blueColour = dist(400, 100, mouseX, mouseY);
var whiteColour = dist(490, 100, mouseX, mouseY);
var blackColour = dist(580, 100, mouseX, mouseY);
var skyGradient = map(mouseY, 0, height, 0, 255);

// Draw either with a gradient or with the set colour
noStroke();
fill(0, skyGradient, 255);
if (mouseIsPressed && backgroundColour > brushSize / 2 && redColour > brushSize / 2 && blueColour > brushSize / 2 && whiteColour > brushSize / 2 && blackColour > brushSize / 2 && redFill == 111) {
ellipse(mouseX, mouseY, brushSize, brushSize);
}
fill(redFill, greenFill, blueFill);
if (mouseIsPressed && backgroundColour > brushSize / 2 && redColour > brushSize / 2 && blueColour > brushSize / 2 && whiteColour > brushSize / 2 && blackColour > brushSize / 2 && redFill != 111) {
ellipse(mouseX, mouseY, brushSize, brushSize);
}

}

function mousePressed() {

// Set where the distances are measuring for the colour buttons
var backgroundColour = dist(220, 100, mouseX, mouseY);
var redColour = dist(310, 100, mouseX, mouseY);
var blueColour = dist(400, 100, mouseX, mouseY);
var whiteColour = dist(490, 100, mouseX, mouseY);
var blackColour = dist(580, 100, mouseX, mouseY);

// Set the colour values based on which button has been clicked on
if (backgroundColour < brushSize / 2 && mouseIsPressed) {
redFill = 111;
}
if (redColour < brushSize / 2 && mouseIsPressed) {
redFill = 247;
greenFill = 10;
blueFill = 38;
}
if (blueColour < brushSize / 2 && mouseIsPressed) {
redFill = 2;
greenFill = 98;
blueFill = 159;
}
if (whiteColour < brushSize / 2 && mouseIsPressed) {
redFill = 255;
greenFill = 255;
blueFill = 255;
}
if (blackColour < brushSize / 2 && mouseIsPressed) {
redFill = 0;
greenFill = 0;
blueFill = 0;
}

}

function keyPressed() {

// Increase and decrease the brush size with the [ and ] keys
if (keyCode == 221 && brushSize < 70) {
brushSize += 5;
}
if (keyCode == 219 && brushSize > 5) {
brushSize -= 5;
}

}

Spider-Man Uncoloured.png

Spider-Man Coloured.png

In class we discussed how out of very simple rules, we can create a vast amount of complexity in an algorithmic system. This subject particularly, is focused on the interest in creating algorithms that generate scenarios that repeat in an interesting, interactive manner. We want to expand on creating artworks that aren’t just static like the ones we have made so far by making artworks that actually do something.

An interesting example of an artwork that uses a repetitive sequence was Conway’s Game of Life. You can see below that program is using simple instructions to generate a repetitive movement that has an interesting visual effect.

via Wikipedia

From my experience with design and programming, I found it very relevant to hear design programming being compared to evolution. Your work keeps evolving until you reach the best, absolute optimum version of your work. An excellent example of this is how the NASA spacecraft antenna uses an automatic computer design program with an algorithm that mimics evolution in order to reach a very specific goal.

Often interesting computer artworks are found by breaking stuff, by stumbling across interest effects by accident. So far in this course I have only done basic kinds of artwork where I have known exactly what I wanted to generate beforehand, so I wanted to try and create something interesting by just playing around with code and seeing where it took me.

I ended up writing some code that will place a circle of random size and colour in a random spot on the screen. The circles can continually be added by pressing the down arrow on the keyboard and they continually bounce up and down off the top and bottom of the canvas. This is all thanks to some instructive, looping code. I also used some of my previous coding knowledge to create an array, making my code even shorter and more efficient. You can try it for yourself here and see what interesting effects it creates for you.

/*
* @name Flow and Response
* @author Tim Dickson
* @description An artwork that was created by playing around with code and seeing what happened.
*/

// Setup the arrays and index
var circleDown = [];
var circleDownWidth = [];
var circleDownHeight = [];
var circleDownRed = [];
var circleDownGreen = [];
var circleDownBlue = [];
var circleDownSize = [];
var circleDownHitBottom = [];
var i = 0;
var pressArrowText = 'Press the down arrow!';

function setup() {

// Set the canvas size
createCanvas(1000, 1200);

}

function draw() {

// Set the background colour
background(255);

// Add instructional text
fill(0);
textSize(50);
textAlign(CENTER);
text(pressArrowText, width / 2, 150);

// Run through all of the circles in the array
for (var ii = 0; ii <= circleDownWidth.length; ii ++) {

// Set the colour and draw the circle
fill(circleDownRed[ii], circleDownGreen[ii], circleDownBlue[ii])
circleDown[ii] = ellipse(circleDownWidth[ii], circleDownHeight[ii], circleDownSize[ii], circleDownSize[ii]);

// Make the circles bounce back when they hit the top or the bottom
if (circleDownHeight[ii] < height - 50 && circleDownHitBottom[ii] == false) {
circleDownHeight[ii] += 5;
} else if (circleDownHeight[ii] >= height - 50 && circleDownHitBottom[ii] == false) {
circleDownHitBottom[ii] = true;
} else if (circleDownHeight[ii] > 50 && circleDownHitBottom[ii] == true) {
circleDownHeight[ii] -= 5;
} else if (circleDownHeight[ii] <= 50 && circleDownHitBottom[ii] == true) {
circleDownHitBottom[ii] = false;
}
}

}

function keyPressed() {

// Generate a new circle whenever the down arrow key is pressed
if (keyCode == DOWN_ARROW) {
circleDownRed[i] = random(100, 255);
circleDownGreen[i] = random(100, 255);
circleDownBlue[i] = random(100, 255);
circleDownWidth[i] = random(width);
circleDownHeight[i] = random(height);
circleDownSize[i] = random(250);
circleDownHitBottom[i] = false;
i ++;
pressArrowText = '';
}

}
Flow and Response.png

Update: After someone in my class thought there was an error with my coding because nothing loaded initially, I decided to add some instructional text in to tell the user to press the down arrow.

Tim Dickson – Blog 2

This week on Kadenze we looked at variables and loops, which we can use to make programs more exciting. Variables are a way to store, modify and re-use data. If you are typing a value more than once you should consider turning it into a variable to make it less repetitive and easier to understand. A variable is defined by:

 

var name = value;

 

The variable name is what you reference it by and it can contain numbers and underscores. It is typically a good idea to make variable names match as closely as possible to their intended use so that you can express what you’re thinking as you are writing your program and in turn make your code easier to read. Here is an example of how a variable works: 

 

var circleDiameter = 55;
ellipse(100, 100, circleDiameter, circleDiameter);
ellipse(200, 100, circleDiameter, circleDiameter);

 

As we learnt last week, the first two values in the ellipse set the centre x and y positions and the third and fourth values set the width and height. As I have created a variable that has a value of 55, I can replace the width and height values with that variable’s name in order to get it’s value. I could instantly see how this will come in handy when you need a value multiple times throughout the code. In this particular instance, if I ever need to change the diameter of both circles I only need to change one value instead of four separate values. I believe that that is a very valuable feature for coding efficiency.

 

If that wasn’t already making it easy enough, p5.js also has some built in variables that we don’t even need to set values for. The ones that we covered in this tutorial were:

  • width
  • height
  • windowWidth
  • windowHeight

 

I also find it very convenient that variables can be used mathematically. For example, the following line would position a circle directly in the centre of the canvas as the x and y centre values are half of the canvas width and height:

 

ellipse(width / 2, height / 2, 100, 100);

 

p5.js runs one line after the other, as we learnt last week, which also gives us the ability to be able to change variables later on in the code after they have already been set.

 

Loops on the other hand, use the following code:

 

for (init; test; update) {
statements
}

 

Where:

  • For tells the loop to run while the conditions are met.
  • Init sets the values of the variables in preparation to run the loop.
  • Test sets the value that is checked on each iteration to see if the loop should continue.
  • Update runs at the end of each loop to change the value of the variables before the loop is run again.
  • Statements are what you want to happen during each iteration.

 

We can use symbols in these loops such as:

  • ++ to increment values by one or += to increment values by a set value.
  • — to decrease values by one or -= to decrease values by a set value.
  • > to check if a value is greater than or >= to check if a value is greater than or equal to.
  • < to check if a value is less than or <= to check if a value is less than or equal to.

 

Loops have the potential to do some really cool things like:

  • You can use variables in them to make the code easier to understand.
  • You can create multiple shapes in a row by repeating them in different x or y positions.
  • You can create gradients by incrementing colour variables.
  • You can use a loop inside a loop to repeat objects vertically and horizontally at the same time.

 

Using loops will help to shorten the code and create less potential for mistakes, making the program less buggy and better overall. It was also very interesting to hear code being compared to music notation. As in they are both well defined formal systems that allow people who know the notation to both read and write it. Just like how music notation defines notes, rest and tempo; code defines statements, loops and conditions.

 

Like last week, I wanted to use what I had learnt to try and create something from it. I wanted to create something with lots of patterns, that repeat both horizontally and vertically (so I could use loops inside each other), and that I could use a gradient in. I thought that I would be able to make great use of this through drawing an American Flag.

 

https://giphy.com/embed/1lk1IcVgqPLkA

via GIPHY

 

This expanded on what we learnt last week and used new skills which included:

  • Variables
  • Loops
  • Loops inside loops
  • Gradients

 

Funnily enough, the hardest part in drawing this was figuring out how to replicate a star. I couldn’t find any included references for drawing a star so I attempted to draw it as a custom shape. This involved using CAD software to plot out my lines and find out where exactly I had to place the vertices in my code. As you can see in the image below I drew a star with a height of 35 and then measured out where the x and y positions of each point were. I’m sure that there would be an easier way of drawing a star in p5.js as this was pretty complicated, but it did do the trick. Thanks to the loop function though, I only had to figure out the stars points once and then I let incrementation take care of the rest of them.

 

5 Point Star.png

 

Having never really used coding to draw things before, I was amazed at what you could draw with such a short amount of code. However, I can already see areas where the code could be reduced even further in the future. I believe that code I have for drawing a star could be turned into some sort of function, so that it only has to be coded once instead of twice. I also think that there will probably be a way to only use one gradient that both increases and decreases, rather than having three separate ones that only do one or the other like I have used.

 

Below is the code that I ended up writing and the resulting artwork; you can also view my work in the editor here.

 

/*
* @name American Flag
* @author Tim Dickson
* @description An American Flag drawn using variables, loops, loops inside loops, and gradients.
*/

function setup() {

// Set the canvas size
createCanvas(1040, 1500);

}

function draw() {

// Set the background colour
background(255);

// Draw and shade the flag pole
var poleWidth = 40;
fill(200);
rect(0, 0, poleWidth, height);
for (var poleShade = 0; poleShade < poleWidth; poleShade ++) {
stroke(poleShade / (poleWidth * 2) * 700, 150);
line(poleShade, 0, poleShade, height);
}

// Set the flag size
var flagWidth = 1000;
var flagHeight = 650;

// Draw the red stripes
var stripeHeight = 50;
fill(178, 34, 52);
noStroke();
for (var stripes = 0; stripes < flagHeight; stripes += stripeHeight * 2) {
rect(poleWidth, stripes, flagWidth, stripeHeight);
}

// Draw the blue box
fill(60, 59, 110);
rect(poleWidth, 0, 420, stripeHeight * 7);

// Draw the first row of white stars
fill(255);
for (var starRow1V = 17.5; starRow1V <= 315; starRow1V += 70) {
for (var starRow1X = 75, starRow1Y = starRow1V; starRow1X <= 425; starRow1X += 70) {
beginShape();
vertex(starRow1X, starRow1Y);
vertex(starRow1X + 11.5, starRow1Y + 35);
vertex(starRow1X - 19, starRow1Y + 13);
vertex(starRow1X + 19, starRow1Y + 13);
vertex(starRow1X - 11.5, starRow1Y + 35);
vertex(starRow1X, starRow1Y);
endShape();
}
}

// Draw the second row of white stars
for (var starRow2V = 17.5; starRow2V <= 280; starRow2V += 70) {
for (var starRow2X = 110, starRow2Y = starRow2V + 35; starRow2X <= 425; starRow2X += 70) {
beginShape();
vertex(starRow2X, starRow2Y);
vertex(starRow2X + 11.5, starRow2Y + 35);
vertex(starRow2X - 19, starRow2Y + 13);
vertex(starRow2X + 19, starRow2Y + 13);
vertex(starRow2X - 11.5, starRow2Y + 35);
vertex(starRow2X, starRow2Y);
endShape();
}
}

// Shade the flag in three transparent gradients
for (var gradient1 = 40; gradient1 < 373; gradient1 ++) {
stroke(gradient1 / flagWidth * 3 * 255, 50);
line(gradient1, 0, gradient1, flagHeight);
}
for (var gradient2A = 373, gradient2B = 255; gradient2A < 706; gradient2A ++, gradient2B --) {
stroke(gradient2B, 50);
line(gradient2A, 0, gradient2A, flagHeight);
}
for (var gradient3A = 706, gradient3B = 0; gradient3A < width; gradient3A ++, gradient3B ++) {
stroke(gradient3B / flagWidth * 3 * 255, 50);
line(gradient3A, 0, gradient3A, flagHeight);
}

}
American Flag.png

 

These new skills progressed into the tutorial where we learnt about the concept of machines having knowledge, which they should be able to use to generate ideas. We looked at specific examples such as:

  • Ashby’s homeostat
  • Stephen Willat’s homeostatic system diagrams
  • Gordon Pask’s ideas on how we enter into conversations with different systems
  • The senster

 

We also discussed how machines hide this information from us, such as the Google search bar where all we see is a text box but we know that it is hiding a lot of complex algorithms behind it. All of this has led to a new way of thinking to create artwork. We are able to replicate analogue artworks digitally and by using the for loop to effectively enable the computer to make decisions, we are able to create some pretty cool things. However, there is a distinction between computer based art and computer art. From my understanding computer based art is more generative and algorithmic, it involves executing artwork in a command based way (our ideas will develop further throughout the semester).

 

After investigating Sol Lewitt’s practice, I found that he was a conceptual artist whose art consisted of lines, basic colours and simplified shapes. He applied these elements according to formulae of his own invention, which was never really predictable nor logical. I was particularly interested in the following artworks, but I found a large variety of his other work here.

via University of Oregon

 

I also found a set of instructions for one of his artworks:

 

USING A BLACK, HARD CRAYON DRAW A TWENTY INCH SQUARE.
DIVIDE THIS SQUARE INTO ONE INCH SQUARES. WITHIN EACH
ONE INCH SQUARE, DRAW NOTHING, OR DRAW A DIAGONAL
STRAIGHT LINE FROM CORNER TO CORNER OR TWO CROSSING
STRAIGHT LINES DIAGONALLY FROM CORNER TO CORNER.

via The Museum of Modern Art

 

I decided to create my own instructions to replicate an artwork similar to those in the picture above:

1. Separate the canvas into three boxed sections.

2. In the first section draw a shape that makes a line in any form (arced, angled, straight, etc.)

3. Repeat the line, making sure each colour is different from the previous, until you completely fill the section.

4. In the next section draw a shape that will create a different type of line.

5. Repeat the line, making sure each colour is different from the previous, until you completely fill the section.

6. In the last section, draw a shape that will create a different type of line again.

7. Repeat the line, making sure each colour is different from the previous, until you completely fill the section.

8. Surround each section with a black border.

 

I then used these instructions to draw the artwork in p5.js. Some new features that I had to look up to be able to do this were:

  • noLoop(); to stop the drawing from running 60 times a second.
  • random(); to generate a random colour using a number range of 255.

 

Something that I love about generated art like this is that you are able to run it over and over and get a unique artwork every single time. Below is the code that I ended up writing and one of the artworks that it generated, but you can also try it for yourself here.

 

/*
* @name Sol LeWitt Inspired Computer Art
* @author Tim Dickson
* @description An artwork that is uniquely generated from a set of instructions each time the program is run.
*/

function setup() {

// Set the canvas size
createCanvas(1000, 1000);

// Stop the drawing from running 60 times a second
noLoop();

}

function draw() {

var r, g, b;

// Draw the circle pattern
for (var circle = 720; circle > 10; circle -= 20, r = random(255), g = random(255), b = random(255)) {
fill(r, g, b);
noStroke();
ellipse(width / 4 * 3, height / 4 * 3, circle, circle);
}

// Draw the vertical pattern
for (var vertical = width / 2; vertical < width; vertical += 10, r = random(255), g = random(255), b = random(255)) {
fill(r, g, b);
noStroke();
rect(vertical, 0, 10, height / 2);
}

// Draw the horizontal pattern
for (var horizontal = 0; horizontal < height; horizontal += 10, r = random(255), g = random(255), b = random(255)) {
fill(r, g, b);
noStroke();
rect(0, horizontal, width / 2, 10);
}

// Draw the borders
stroke(0);
strokeWeight(10);
line(width / 2, 0, width / 2, height);
line(width / 2, height / 2, width, height / 2);
noFill();
rect(5, 5, width - 10, height - 10);

}
Sol LeWitt Inspired Computer Art.png

Tim Dickson – Blog 1

I found it very interesting this week to hear about the co-creative relationship between humans and machines in the context of an era that is very different to today’s digital world. A given example was the design of the Sperry turret, an aircraft aiming system that allowed gunmen to shoot better in World War 2. Just like modern computers, it involved man and machine working together in an autonomous sense, extending the ability of a person to be able to do a particular thing, and allowing them to be able to do something that they haven’t previously been able to do. In this case it was enabling the user to shoot faster and more accurately than ever before. 

via Twitter

via Twitter

 

This idea has carried forward into computer art, where we began to start thinking about how to apply these same principles to a better cause. Out of this we began to see the development of some really interesting things. Using algorithmic machines, we have been able to extend the range of human capacity to be able to produce artworks, drawings, animations, and much more. Below is one of the first examples of algorithmic programming. 

 via YouTube

 

After learning the backgrounds of design programming, I moved on to learning p5.js. Having coding experience with other languages, I was instantly able to recognise that the default template was setting a canvas size and its background colour in rgb format. I began to play around with these settings, changing the size and colour of the canvas, to see how the editor worked and ran. I also looked at some of the available examples, I was very interested in two in particular:

  • The DOM: Input Button example – where a user can input their name and press go, before the code stores their name as a variable and displays it randomly using the set colour and rotation.
  • The Hello P5: weather example – where JSON data is retrieved from a URL and used in the interface.

These, along with many other previewed examples, showed me that this language has a great potential, and I am very excited about what I will be able to do with it by the end of the semester.

 

After watching the first tutorials on Kadenze, I was able to take the following notes from them:

  • Code is a way to encode language and it defines how a computer performs.
  • Learning to code opens new possibilities for exploration and is a vital skill for interactive work with websites, apps, etc.
  • Computers are more than enhanced calculators, they are media machines.
  • p5.js is a new JavaScript based programming library which involves writing software to make images, animations and interactions.
  • p5.js is written one line after another (one piece at a time) and just like us it starts to read from the top and works its way down to the bottom.
  • p5.js is free and open source, and it is constantly evolving to meet the creative needs of the people that use it.

 

And more specifically, this is what I noted about the language:

  • Parentheses separate the name of a function and its argument, arguments go inside the parentheses.
  • Nearly every line ends with a semicolon, defining the statement as complete and telling the next line to run.
  • All code in p5.js is case sensitive (all library references seem to be in camel case).
  • Ellipses are defined using:
    ellipse(centre x, centre y, width, height);

     

  • Rectangles are defined using:
    rect(top left corner x, top left corner y, width, height);

     

  • Canvas is the name of the surface that we are drawing on and is defined using:
    canvas(width, height);

     

  • A line is drawn between two positions and is defined using:
    line(x1, y1, x2, y2);

     

  • The stroke weight is defined before the stroke that you want to have that weight using:
    strokeWeight();

     

  • The fill colour is defined before the shape that you want to have that colour by using:
    fill();

     

  • One fill number represents a greyscale colour and three fill numbers represent an rgb colour, with 255 being the maximum number.
  • Stroke colours are also set the same way using:
    stroke();

     

  • Colours are all opaque by default, transparency can be set by a second argument (greyscale) or fourth argument (rgb).
  • The origin position is set to (0, 0) by default.
  • Strokes can be removed by using:
    noStroke();

     

  • Fills can be removed by using:
    noFill();

     

  • Custom shapes are defined using:
    beginShape();

    followed by however many vertexes:

    vertex(x, y);

    followed by

    endShape();

 

Some other notes that I found useful were that:

  • Using colours in p5.js is like using a crayon box, it will use the colour that you have picked out until you go back and pick a different colour.
  • Tabs and spaces can be used to visually lay out your code (they are ignored when the code is run).
  • More references (such as beginShape and triangle) can be found in the p5.js reference library.

 

Having obtained all of this knowledge on p5.js, I wanted to create something to show what I had learnt. I decided that I wanted to try and draw a character that could be replicated using the simple shapes that we have learnt so far. This is when I decided to try and draw an easily recognisable minion character from Despicable Me.

https://giphy.com/embed/SqmkZ5IdwzTP2

via GIPHY

 

I was able to code the following artwork using all of the features that we have come across so far, including:

  • Background colours
  • noStrokes/noFills
  • Fills
  • Rectangles
  • Ellipses
  • Stroke colours/weights
  • Lines
  • Custom shapes

 

I even went one step further and used the reference library to find out how to draw an arc, because I didn’t think a straight line showed enough facial expression. Below is the code that I ended up writing and the resulting artwork; you can also view my work in the editor here.

/*
* @name Despicable Me Minion
* @author Tim Dickson
* @description A minion drawn using background colours, noStrokes/noFills, fills, rectangles, ellipses, stroke colours/weights, lines, and custom shapes.
*/

function setup() {

// Set the canvas size
createCanvas(640, 1136);

}

function draw() {

// Set the background colour
background(251, 236, 31);

// Draw the Minion's overalls
noStroke();
fill(29, 118, 186);
rect(0, 750, 640, 386);

// Draw the Minion's goggles
fill(35);
rect(0, 225, 640, 125);
fill(205);
ellipse(217.5, 287.5, 240, 240);
ellipse(422.5, 287.5, 240, 240);

// Draw the Minion's buttons
fill(35);
ellipse(50, 800, 50, 50);
ellipse(590, 800, 50, 50);
fill(55);
ellipse(50, 800, 40, 40);
ellipse(590, 800, 40, 40);
stroke(35);
strokeWeight(2.5);
line(50, 785, 50, 815);
line(35, 800, 65, 800);
line(590, 785, 590, 815);
line(575, 800, 605, 800);

// Draw the G logo
noStroke();
fill(14, 55, 86);
ellipse(320, 950, 200, 250);
fill(29, 118, 186);
beginShape();
vertex(320, 830);
vertex(225, 950);
vertex(320, 1070);
vertex(415, 950);
endShape();
fill(14, 55, 86);
ellipse(320, 950, 100, 140);
rect(320, 940, 100, 10);
fill(29, 118, 186);
rect(340, 950, 40, 10);

// Add shadowing
fill(0, 10);
rect(320, 0, 320, 1136);

// Draw the Minion's eyes
fill(255);
ellipse(217.5, 287.5, 185, 185);
ellipse(422.5, 287.5, 185, 185);
fill(137, 93, 58);
ellipse(217.5, 287.5, 100, 100);
ellipse(422.5, 287.5, 100, 100);
fill(0);
ellipse(217.5, 287.5, 50, 50);
ellipse(422.5, 287.5, 50, 50);
fill(255);
ellipse(202.5, 272.5, 25, 25);
ellipse(407.5, 272.5, 25, 25);

// Draw the Minion's smile
stroke(0);
strokeWeight(5);
noFill();
arc(275, 500, 350, 250, 0, 2);

}
Despicable Me Minion