Friday, 22 November 2019

Simulating Lots of Things with Objects and Classes

This month's Cornwall meetup was an introduction to objects and classes, a technique that allows us to intuitively and easily model many many similar things.



The slides for the tutorial are here: [link].


Approach

This session was a continuation of our journey learning creative coding for beginners, specifically with the p5js javascript language using openrprocessing.org. Over months we have worked through key topics such as colour models and recursion from this course designed for newcomers:



Object oriented programming (OOP) is important in the world of programming, and can be very useful for creative coding. Is sometimes seen as complicated, plagued by jargon and without clear reasons for using them.

So the approach taken here is to start with a very simple familiar example, and then try to scale that until we hit a challenge, to which the the solution is objects and classes.


A Simple Moving Ball

We started with the simplest example of a ball displayed on the screen as a circle. We talked about the information that ball required - its location in terms of x and y coordinates, for example.

We then considered how the ball might move, with additional information required about its speed in the horizontal and vertical directions. We considered some very simple code that animated this movement - you can explore the code here: (sketch).

Finally we considered how we might simulate the effect of gravity. Whereas speed updates location, gravity updates speed - a simple way to think about the physics without exploring Newton's equations of motion.


This gave more realistic motion of a ball thrown up and then falling.


You can  explore the code here - (sketch).

So far we have very simple familiar code that models a ball in motion under gravity.


Challenge - Lots of Balls

If we wanted to model, not one but 10, or 100, or even 1000 balls, how would be do that?

We don't want to have 1000 different x and y variables to code individually.

One way of minimising duplication is to take advantage of commonality in the many things we're modelling.


We can see that all these balls have (x,y) coordinates and (x_speed, y_speed) information. They also happen to be the same colour and size.

So we can take these common things and include them into a blueprint.


That blueprint we can make many instances of the ball, each with their own position and velocity. The actual numbers for position and velocity can be different but they all have this information.

This is the basic idea of object oriented programming. We define blueprints, from which we can make many instances.

Conceptually, that's how we solve the challenge of modelling many balls.


Classes and Objects

In programming languages, the blueprints are often called classes. And instances created from a class are called objects.

The classes can contain information like position and velocity. These are just like normal variables, but associated with the class. This information is often called object or class data.

Classes can also contain functions! Yes, that's right. A blueprint for a a thing, like a ball, can have functions associated with that thing. For example, we might have a move() or show() function for a ball. For a computer game character we might have a function explode().  These functions, when associated with classes or objects, are sometimes called methods.


Let's see what this looks like in code. The following shows an example of a class which has both data and methods. You can see it has x and y coordinates for its position. It also has a show() method which draws a circle.


It is worth noting that the constructor() function is special. It is always called when an object is first created. It's the ideal place to initialise and set up the object. Here we set the x and y data.

We then re-wrote the code for our simple ball as a class blueprint, and created an instance of the ball with var my_ball = new Ball(). We then used the animation loop to repeatedly call the object's show() and move() functions to draw the ball and update it's position.

You can explore the code here  - (sketch). It is instructive to see where our previous code goes in this object oriented code.


Lots of Objects!

It might appear that we've written more code just to get a ball to move under the influence of gravity. The benefit is that we can create lots of instances of the ball blueprint very easily.

We saw how we can fill a list with newly created Ball objects.


Our example code had a list of 20 balls. In the code we simply iterate over the list at every animation frame to move and show the balls.

Each one of these 20 ball objects has its own position and velocity. To ensure they don't all follow the same path, we added a random element to the initial velocity in the constructor() in the class definition.

The result is rather pleasing!


You can explore the code here - (sketch).

The power of objects and classes is now clear.

We can easily create many objects from a single blueprint. You can see how this can be used to model many kinds of things, from flocking birds to creeping ants .. our imagination is the only limit.


Simple Examples

We looked at some simple examples, which share the same code structure, but model different scenarios.

The simple balls example can be adapted to model bouncing when hitting an edge to create the effect of balls bouncing in a jar.


The code is here - (sketch), and worth looking at to see how easy it is to extend the blueprint to include these new effects.

Once the blueprint is updated, all the balls benefit. This is good way to keep more complex coding projects tidy and manageable.

The next example was a simulation of fireworks, but the core element is the same as our balls flying under the influence of gravity.


Explore the code is here - (sketch). Most of the additional code is simply to style the moving balls.

Finally we looked at an example which wasn't based on objects moving under gravity, but moving according to Perlin noise.



You can explore the code here - (sketch).  It is useful to see which code is similar to all our previous example. The definition of a blueprint, the creation of many objects in a list, and then repeatedly calling methods on those objects, is the common pattern.


Thoughts

There are many algorithmic artists, and indeed scientists and engineers, who model the behaviour of many similar things. Using classes an objects is one common way of doing this elegantly.

Conceptually, the idea of being able to flexibly define "things" which have the characteristics of real or imaging things is nice. We can create, for example, dogs, which might have colour and name, and methods like run and bark.

This object oriented programming is popular, and is possible in many languages, from Python to Java, from Javascript to C++. The syntax and terminology might vary, but the concepts are similar.

In this session we introduced objects and classes. You can do much more with objects and classes, such as creating hierarchies of blueprints, but most algorithmic art is very effective with just the simple ideas we covered.

No comments:

Post a Comment