Wednesday 26 August 2009

Example program



Here's a small program that shows some bouncing balls interacting with each other, changing colour when they collide with another ball, to become either lighter or darker.

I've re-used an existing example that comes with processing, the BouncyBubbles program (found in the Examples menu under Topics/Motion).


/**
* Bouncy Bubbles.
* Based on code from Keith Peters (www.bit-101.com).
*
* Multiple-object collision.

* Ammended by Richard Brown to add color routines
*/


int numBalls = 20;
float spring = 0.05;
float gravity = 0.03;
float friction = -0.9;
Ball[] balls = new Ball[numBalls];

void setup()
{
size(640, 200);
noStroke();
smooth();
for (int i = 0; i < numBalls; i++) {
balls[i] = new Ball(random(width), random(height), random(20, 40), i, balls);
}
}

void draw()
{
background(128);
for (int i = 0; i < numBalls; i++) {
balls[i].collide();
balls[i].move();
balls[i].display();
}
}

class Ball {
float x, y;
float diameter;
float vx = 0;
float vy = 0;
int id;
int brighten=0;

Ball[] others;
color ourColor;
color colorArray[]={
color(255,0,0),
color(0,255,0),
color(0,0,255),
color(240,150,40)
};

Ball(float xin, float yin, float din, int idin, Ball[] oin) {
x = xin;
y = yin;
if (random(1)>0.5)
brighten = 1;
else
brighten = 0;
diameter = din;
id = idin;
others = oin;
int numberOfColors=colorArray.length;
ourColor=colorArray[int(random(numberOfColors))];
}

void collide() {
for (int i = id + 1; i < numBalls; i++) {
Ball ball=others[i];
float dx = others[i].x - x;
float dy = others[i].y - y;
float distance = sqrt(dx*dx + dy*dy);
float minDist = others[i].diameter/2 + diameter/2;
if (distance < minDist) {
float angle = atan2(dy, dx);
float targetX = x + cos(angle) * minDist;
float targetY = y + sin(angle) * minDist;
float ax = (targetX - others[i].x) * spring;
float ay = (targetY - others[i].y) * spring;
vx -= ax;
vy -= ay;
others[i].vx += ax;
others[i].vy += ay;
ourColor=lerpColor(ourColor,others[i].ourColor,0.1);
if (brighten==1)
// brighten the other ball by 10%
ball.ourColor=brightenColor(ball.ourColor,1.1);
else
// darken the ball
ball.ourColor=brightenColor(ball.ourColor,0.9);
}
}
}

void move() {
vy += gravity;
x += vx;
y += vy;
if (x + diameter/2 > width) {
x = width - diameter/2;
vx *= friction;
}
else if (x - diameter/2 < 0) {
x = diameter/2;
vx *= friction;
}
if (y + diameter/2 > height) {
y = height - diameter/2;
vy *= friction;
}
else if (y - diameter/2 < 0) {
y = diameter/2;
vy *= friction;
}
}

void display() {
fill(ourColor);
ellipse(x, y, diameter, diameter);
}
}

int brightenElement(float element,float percentage)
{
element=(element*percentage);
if (element>255)
element=255;
return (int)element;
}

// brightenColor
// brightens a colour by a percentage
// percentage should be a float e.g. 1.10 to
// brighten by 10%, or 0.75 to darken by 25%
// returns the new colour
color brightenColor(color c,float percentage)
{
int r=brightenElement(red(c),percentage);
int g=brightenElement(green(c),percentage);
int b=brightenElement(blue(c),percentage);
return color(r,g,b);
}

Sunday 23 August 2009

Extra colour functions

A range of extra functions are available to provide information about colours.
red(), green() and blue() provide access to the individual components of a colour.

These functions return float values, which makes them quite slow in practice.

This code snippet shows a method of brightening a colour by accessing the components:


// brightenColour
// an example showing basic colour manipulation
// using red(), green() and blue()

void setup()
{
size(400, 400);
smooth();
noStroke();
}

void draw()
{
int h=100;
int y=0;
color c = color(230,185,80);
for (int i=0; i<4; i++) {
fill(c);
rect(0,y,width,y+h);
c=brightenColor(c,1.10); // brighten the colour by 10%
y+=h;
}
}

int brightenElement(float element,float percentage)
{
element=(element*percentage);
if (element>255)
element=255;
return (int)element;
}

// brightenColor
// brightens a colour by a percentage
// percentage should be a float e.g. 1.10 to
// brighten by 10%, or 0.75 to darken by 25%
// returns the new colour
color brightenColor(color c,float percentage)
{
int r=brightenElement(red(c),percentage);
int g=brightenElement(green(c),percentage);
int b=brightenElement(blue(c),percentage);
return color(r,g,b);
}

Tuesday 18 August 2009

lerpColor

The oddly named lerpColor provides another colour function. Lerp is short for linear interpolation, a simple means of finding values between a start and end position.

Here's a small program snippet which draws a series of decreasing squares, gradually changing from the first colour (in this case red) to the second (orange):


// lerpColor() example program
size(400, 400);
noStroke();
// set the two colours to draw a gradient between
color red = color(255,0,0);
color orange = color(240,150,40);
// choose the number of steps - the more the smoother the gradient
int number_of_steps=50;
float percentage_per_step = 1.0 / number_of_steps;
for (int i=0; i<number_of_steps; i++) {
fill(lerpColor(red,orange,percentage_per_step*i));
int border=i*((height/2)/number_of_steps);
rect(border,border,width-border-border,height-border-border);
}

Friday 20 March 2009

Chunk 73. More colour functions

blendColor provides a simple method of combing two colours to create a new one.
For example if we add together a red and green we will see yellow.

This simple example draws three rectangles - one each in red and green, and
one in the color formed by adding them.

We'd expect this colour to be yellow, as you'd get by combining colours normally.


size(400, 400);
smooth();
noStroke();
color red = color(255,0,0);
color green = color(0,255,0);
color red_add_green=blendColor(red,green,ADD);
fill(red);
rect(0,0,width/2,height);
fill(green);
rect(width/2,0,width/2,height);
// background
fill(red_add_green);
rect(width/4, width/4, width/2, height/2);


To understand exactly how these work to create a new colour, consider they way colours are defined.
When we write
color red = color(255,0,0);

We're creating a colour with a red component of 255, a green component of 0 and a blue component of 0.
Not suprisingly the colour is pure red.

When we use blendColor() to ADD a colour, it adds each of the components to create a new colour with those components.
So for our first example, adding red and green, we are adding components (255,0,0) and (0,255,0).
blendColor combines these to form a new colour with the components (255,255,0) which corresponds to yellow.

Tuesday 10 February 2009

Getting Started

Hi,

this is my contribution to Darrel Ince's Mass Writing project.

Step 1. Creating this blog