Back to photostream

spinning-collisions-01

Sketch created in Processing 3 for Creative Coding course: Week 3: extend the spinning top sketch.

 

The code follows:

 

/*

* Creative Coding

* Week 3, 04

* extending spinning top: based on work

* by Indae Hwang and Jon McCormack

* Updated 2016

* Copyright (c) 2014-2016 Monash University

*

* Pool balls collide, spin and absorb each other.

*

*/

 

 

int num; // the number of items in the array

float[] ballX; // x-position of ball

float[] ballY; // y-position of ball

float[] ballSpeed; // speed of movement of ball

float[] ballDirection; // direction of movement of ball in radians

float[] ballSpin; // spin (rotation speed and direction) of ball

float[] ballBaseline; // baseline of spinning ball text

color[] ballColour; // colour of ball

int [] ballSize; // current radius of ball

int [] ballCollisionState; // 0 = waiting for collision; 1 = in collision

float entropyValue = 0.98; // fraction of 'energy' retained after collisions etc.

color backgroundColour = #000000;

color baizeColour = #46AA4A;

color tableColour = #C1953B;

color colourFrom = #FF0000; // starts colour range of balls

color colourTo = #0000FF; // ends colour range of balls

int tableHeight = 480;

int tableWidth = 360;

int tableEdgedepth = 30;

int ballRadius = 15;

float spinEffect = 1.1; // how much spin adds to bounce angles off side

int opacity = 50;

// dimension variables

int centreX;

int centreY;

int centreLeft;

int centreRight;

int centreTop;

int centreBottom;

 

 

void setup() {

size(400, 520);

// initialise dimension variables

centreX = width/2;

centreY = height/2;

centreLeft = width/2 - tableWidth/2 - tableEdgedepth/2;

centreRight = width/2 + tableWidth/2 + tableEdgedepth/2;

centreTop = height/2 - tableHeight/2 - tableEdgedepth/2;

centreBottom = height/2 + tableHeight/2 + tableEdgedepth/2;

 

 

num = 8; // number of balls

 

 

// allocate size of arrays

ballX = new float[num];

ballY = new float[num];

ballSpeed = new float[num];

ballDirection = new float[num];

ballSpin = new float[num];

ballBaseline = new float[num];

ballColour = new color[num];

ballSize = new int[num];

ballCollisionState = new int[num];

 

 

// initial position of ball 0 in the top half of the screen

ballX[0] = centreX;

ballY[0] = centreTop + 2 * tableEdgedepth;

ballSpeed[0] = random(8, 12);

ballDirection[0] = PI*9.0/20.0 + random(PI/10.0);

//ballDirection[0] = PI/2;

//ballDirection[0] = PI/4;

ballSpin[0] = random(PI) - PI/2;

ballBaseline[0] = 0.0;

ballColour[0] = #FFFFFF;

ballSize[0] = ballRadius;

ballCollisionState[0] = 0;

 

// initialise positions of rest of balls

for (int i = 1; i < ballX.length; i++) {

ballX[i] = random(centreLeft + 2 * tableEdgedepth, centreRight - 2 * tableEdgedepth);

ballY[i] = random(centreTop + 4 * tableEdgedepth, centreBottom - 2 * tableEdgedepth);

ballSpeed[i] = 0.0;

ballDirection[i] = 0.0;

ballSpin[i] = 0.0;

ballBaseline[i] = 0.0;

ballColour[i] = lerpColor(colourFrom, colourTo, (i - 1.0)/(num - 2.0));

ballSize[i] = ballRadius;

ballCollisionState[i] = 0;

}

 

 

// draw background objects

background(0);

noStroke();

rectMode(CENTER);

fill(baizeColour);

rect(centreX, centreY, tableWidth - tableEdgedepth, tableHeight - tableEdgedepth);

fill(tableColour);

rect(centreLeft, centreY, tableEdgedepth, tableHeight); //left

rect(centreRight, centreY, tableEdgedepth, tableHeight); //right

rect(centreX, centreTop, tableWidth, tableEdgedepth); //top

rect(centreX, centreBottom, tableWidth, tableEdgedepth); //bottom

 

// text settings

textSize(ballRadius);

textAlign(CENTER, CENTER);

}

 

 

void draw() {

 

 

// blend the old frames into the background

blendMode(BLEND);

stroke(0, opacity);

// draw balls

for (int i = 0; i 0.0) {

fill(ballColour[i], opacity);

ellipse(ballX[i], ballY[i], ballSize[i], ballSize[i]);

translate(ballX[i], ballY[i]);

rotate(ballBaseline[i]);

fill(0, opacity);

textSize(ballSize[i]);

text(i, 0, 0);

resetMatrix();

}

}

// move balls

for (int i = 0; i < ballX.length; i++) {

float dx = cos(ballDirection[i]) * ballSpeed[i];

float dy = sin(ballDirection[i]) * ballSpeed[i];

ballX[i] += dx;

ballY[i] += dy;

}

// collision detection

// with sides

for (int i = 0; i < ballX.length; i++) {

if (ballX[i] centreRight - tableEdgedepth) {

ballDirection[i] = (-1 * PI - ballDirection[i]) * spinEffect;

}

if (ballY[i] centreBottom - tableEdgedepth) {

ballDirection[i] = (-1 * ballDirection[i]) * spinEffect;

}

}

// with other balls

for (int i = 0; i < ballX.length; i++) {

for (int j = 0; j < ballX.length; j++) {

if (i != j) { // a ball cannot collide with itself

if (dist(ballX[i], ballY[i], ballX[j], ballY[j]) <= ballRadius) {

if (ballCollisionState[i] == 0 && ballCollisionState[j] == 0) {

ballCollisionState[i] = 1;

ballCollisionState[j] = 1;

ballCollision(i, j);

}

} else {

ballCollisionState[i] = 0;

}

}

}

}

 

// spin balls

for (int i = 0; i ballSpeed[ball2] ? ball1 : ball2;

int loser = winner == ball1 ? ball2 : ball1;

ballSpeed[winner] = ballSpeed[ball1] + ballSpeed[ball2] * entropyValue;

ballSpeed[loser] = 0.0;

ballDirection[winner] = (ballDirection[ball1] + ballDirection[ball2] / 2) / PI;

float r1 = ballSize[ball1];

float r2 = ballSize[ball2];

ballSize[winner] = (int) sqrt(sq(r1) + sq(r2));

ballSize[loser] = 0;

ballColour[winner] = lerpColor(ballColour[winner], ballColour[loser], 0.4);

}

ballSpin[ball1] = ballSpin[ball1] * entropyValue / 2;

ballSpin[ball2] = ballSpin[ball1] * -1;

}

 

 

501 views
1 fave
0 comments
Uploaded on August 18, 2016