Monday, June 20, 2011
smokeSplit
// just type here
// and click "save" when your done
//smoke ribbon
//
//Developed by sacculi based on code from zenbullets
//
// Dec 2008
// http://www.abandonedart.org
// http://www.zenbullets.com
//
// with lots of thanks to Erik Natzke (obviously)
// http://jot.eriknatzke.com/
//
// and James Alliban, who saved me the job of doing the conversion
// http://jamesalliban.wordpress.com/2008/12/04/2d-ribbons/
//
//
// This work is licensed under a Creative Commons 3.0 License.
// (Attribution - NonCommerical - ShareAlike)
//
// This basically means, you are free to use it as long as you:
// 1. give http://www.zenbullets.com a credit
// 2. dont use it for commercial gain
// 3. share anything you create with it in the same way I have
//
//Thanks zen bullets! (Matt Pearson) from sacculi (Will Pearson)
//================================= global vars
int _numRibbons = 3; //6
int _numParticles = 10; //40
float _randomness = .3;
RibbonManager ribbonManager;
float _a, _b, _centx, _centy, _x, _y;
float _ribbon1x, _ribbon1y, _ribbon2x, _ribbon2y, _ribbon3x, _ribbon3y;
float _noiseoff;
int _angle;
//================================= init
void setup() {
size(800,600);
background(255);
clearBackground();
//the original ribbon here...
_centx = (width / 2);
_centy = (height / 2);
//the other 3 suspects
//_ribbon1x = 0;
// _ribbon1y = height;
//_ribbon2x = width;
//_ribbon2y = height;
//_ribbon3x = width;
// _ribbon3y = 0;
restart();
}
void restart() {
_noiseoff = random(1);
_angle = 1;
_a = 3.5;
_b = _a + (noise(_noiseoff) * 1) - 0.5;
ribbonManager = new RibbonManager(_numRibbons, _numParticles, _randomness);
ribbonManager.setRadiusMax(40); // default = 8
ribbonManager.setRadiusDivide(2); // default = 10
ribbonManager.setGravity(-0.09); // default = .03
ribbonManager.setFriction(1.1); // default = 1.1
ribbonManager.setMaxDistance(40); // default = 40
ribbonManager.setDrag(2.5); // default = 2
ribbonManager.setDragFlare(.015); // default = .008
}
void clearBackground() {
background(0);
}
//================================= frame loop
void draw() {
clearBackground();
float newx = sin(_a + radians(_angle) + PI / 2) * _centx;
float newy = sin(_b + radians(_angle)) * _centy;
_angle = int(random(360));
_noiseoff += 0.05;
_b = (noise(_noiseoff) * 8) +1;
_a = _b;
translate(_centx, _centy);
scale(5);
ribbonManager.update(newx* 0.1, newy*0.1);
rotate(20);
ribbonManager.update(newx* 0.1, newy*0.1);
rotate(20);
ribbonManager.update(newx* 0.1, newy*0.1);
rotate(20);
ribbonManager.update(newx* 0.1, newy*0.1);
rotate(20);
ribbonManager.update(newx* 0.1, newy*0.1);
/*
translate(_ribbon1x, _ribbon1y);
ribbonManager.update(newx* 0.1, newy*0.1);
translate(_ribbon2x, _ribbon2y);
ribbonManager.update(newx* 0.1, newy*0.1);
translate(_ribbon3x, _ribbon3y);
ribbonManager.update(newx* 0.1, newy*0.1);
*/
}
//================================= interaction
void mousePressed() {
}
//================================= objects
// modified from original code by http://jamesalliban.wordpress.com/
//======== manager
class RibbonManager {
// PImage img;
int _numRibbons;
int _numParticles;
float _randomness;
Ribbon[] ribbons;
/* Ribbon[] ribbons1;
Ribbon[] ribbons2;
Ribbon[] ribbons3; */ // ribbon array
RibbonManager(int _numRibbons, int _numParticles, float _randomness) {
this._numRibbons = _numRibbons;
this._numParticles = _numParticles;
this._randomness = _randomness;
init();
}
void init() {
addRibbon();
}
void addRibbon() {
ribbons = new Ribbon[_numRibbons];
/*ribbons1 = new Ribbon[_numRibbons];
ribbons2 = new Ribbon[_numRibbons];
ribbons3 = new Ribbon[_numRibbons];*/
for (int i = 0; i < _numRibbons; i++) {
color ribbonColour = color(random(255), ((40/_numRibbons) * i) ) ;
ribbons[i] = new Ribbon(_numParticles, ribbonColour, _randomness);
/* ribbons1[i] = new Ribbon(_numParticles, ribbonColour, _randomness);
ribbons2[i] = new Ribbon(_numParticles, ribbonColour, _randomness);
ribbons3[i] = new Ribbon(_numParticles, ribbonColour, _randomness);*/
}
}
void update(float currX, float currY) {
for (int i = 0; i < _numRibbons; i++)
{
float randX = currX;
float randY = currY;
ribbons[i].update(randX, randY);
/* ribbons1[i].update(randX, randY);
ribbons2[i].update(randX, randY);
ribbons3[i].update(randX, randY);*/
}
}
void setRadiusMax(float value) {
for (int i = 0; i < _numRibbons; i++) {
ribbons[i].radiusMax = value;
}
}
void setRadiusDivide(float value) {
for (int i = 0; i < _numRibbons; i++) {
ribbons[i].radiusDivide = value;
}
}
void setGravity(float value) {
for (int i = 0; i < _numRibbons; i++) {
ribbons[i].gravity = value;
}
}
void setFriction(float value) {
for (int i = 0; i < _numRibbons; i++) {
ribbons[i].friction = value;
}
}
void setMaxDistance(int value) {
for (int i = 0; i < _numRibbons; i++) {
ribbons[i].maxDistance = value;
}
}
void setDrag(float value) {
for (int i = 0; i < _numRibbons; i++) {
ribbons[i].drag = value;
}
}
void setDragFlare(float value) {
for (int i = 0; i < _numRibbons; i++) {
ribbons[i].dragFlare = value;
}
}
}
//======== ribbon
class Ribbon {
int _numRibbons;
float _randomness;
int _numParticles; // length of the Particle Array (max number of points)
int particlesAssigned = 0; // current amount of particles currently in the Particle array
float radiusMax = 16; // maximum width of ribbon
float radiusDivide = 30; // distance between current and next point / this = radius for first half of the ribbon
float gravity = .06; // gravity applied to each particle
float friction = 1.1; // friction applied to the gravity of each particle
int maxDistance = 40; // if the distance between particles is larger than this the drag comes into effect
float drag = 2; // if distance goes above maxDistance - the points begin to grag. high numbers = less drag
float dragFlare = .008; // degree to which the drag makes the ribbon flare out
RibbonParticle[] particles; // particle array
color ribbonColor;
Ribbon(int _numParticles, color ribbonColor, float _randomness) {
this._numParticles = _numParticles;
this.ribbonColor = ribbonColor;
this._randomness = _randomness;
init();
}
void init() {
particles = new RibbonParticle[_numParticles];
}
void update(float randX, float randY) {
addParticle(randX, randY);
drawCurve();
}
void addParticle(float randX, float randY) {
if(particlesAssigned == _numParticles) {
for (int i = 1; i < _numParticles; i++) {
particles[i-1] = particles[i];
}
particles[_numParticles - 1] = new RibbonParticle(_randomness, this);
particles[_numParticles - 1].px = randX;
particles[_numParticles - 1].py = randY;
return;
}
else {
particles[particlesAssigned] = new RibbonParticle(_randomness, this);
particles[particlesAssigned].px = randX;
particles[particlesAssigned].py = randY;
++particlesAssigned;
}
if (particlesAssigned > _numParticles) ++particlesAssigned;
}
void drawCurve() {
smooth();
for (int i = 1; i < particlesAssigned - 1; i++) {
RibbonParticle p = particles[i];
p.calculateParticles(particles[i-1], particles[i+1], _numParticles, i);
}
fill(30);
for (int i = particlesAssigned - 3; i > 1 - 1; i--) {
RibbonParticle p = particles[i];
RibbonParticle pm1 = particles[i-1];
//fill(ribbonColor, 255);
fill(255, 255);
if (i < particlesAssigned-3) {
noStroke();
beginShape();
vertex(p.lcx2, p.lcy2);
bezierVertex(p.leftPX, p.leftPY, pm1.lcx2, pm1.lcy2, pm1.lcx2, pm1.lcy2);
vertex(pm1.rcx2, pm1.rcy2);
bezierVertex(p.rightPX, p.rightPY, p.rcx2, p.rcy2, p.rcx2, p.rcy2);
vertex(p.lcx2, p.lcy2);
endShape();
}
}
}
}
//======== particle
class RibbonParticle {
float px, py; // x and y position of particle (this is the bexier point)
float xSpeed, ySpeed = 0; // speed of the x and y positions
float cx1, cy1, cx2, cy2; // the avarage x and y positions between px and py and the points of the surrounding Particles
float leftPX, leftPY, rightPX, rightPY; // the x and y points of that determine the thickness of this segment
float lpx, lpy, rpx, rpy; // the x and y points of the outer bezier points
float lcx1, lcy1, lcx2, lcy2; // the avarage x and y positions between leftPX and leftPX and the left points of the surrounding Particles
float rcx1, rcy1, rcx2, rcy2; // the avarage x and y positions between rightPX and rightPX and the right points of the surrounding Particles
float radius; // thickness of current particle
float _randomness;
Ribbon ribbon;
RibbonParticle(float _randomness, Ribbon ribbon) {
this._randomness = _randomness;
this.ribbon = ribbon;
}
void calculateParticles(RibbonParticle pMinus1, RibbonParticle pPlus1, int particleMax, int i) {
float div = 2;
cx1 = (pMinus1.px + px) / div;
cy1 = (pMinus1.py + py) / div;
cx2 = (pPlus1.px + px) / div;
cy2 = (pPlus1.py + py) / div;
// calculate radians (direction of next point)
float dx = cx2 - cx1;
float dy = cy2 - cy1;
float pRadians = atan2(dy, dx);
float distance = sqrt(dx*dx + dy*dy);
if (distance > ribbon.maxDistance) {
float oldX = px;
float oldY = py;
px = px + ((ribbon.maxDistance/ribbon.drag) * cos(pRadians));
py = py + ((ribbon.maxDistance/ribbon.drag) * sin(pRadians));
xSpeed += (px - oldX) * ribbon.dragFlare;
ySpeed += (py - oldY) * ribbon.dragFlare;
}
ySpeed += ribbon.gravity;
xSpeed *= ribbon.friction;
ySpeed *= ribbon.friction;
px += xSpeed + random(.3);
py += ySpeed + random(.3);
float randX = ((_randomness / 2) - random(_randomness)) * distance;
float randY = ((_randomness / 2) - random(_randomness)) * distance;
px += randX;
py += randY;
//float radius = distance / 2;
//if (radius > radiusMax) radius = ribbon.radiusMax;
if (i > particleMax / 2) {
radius = distance / ribbon.radiusDivide;
}
else {
radius = pPlus1.radius * .9;
}
if (radius > ribbon.radiusMax) radius = ribbon.radiusMax;
if (i == particleMax - 2 || i == 1) {
if (radius > 1) radius = 1;
}
// calculate the positions of the particles relating to thickness
leftPX = px + cos(pRadians + (HALF_PI * 3)) * radius;
leftPY = py + sin(pRadians + (HALF_PI * 3)) * radius;
rightPX = px + cos(pRadians + HALF_PI) * radius;
rightPY = py + sin(pRadians + HALF_PI) * radius;
// left and right points of current particle
lpx = (pMinus1.lpx + lpx) / div;
lpy = (pMinus1.lpy + lpy) / div;
rpx = (pPlus1.rpx + rpx) / div;
rpy = (pPlus1.rpy + rpy) / div;
// left and right points of previous particle
lcx1 = (pMinus1.leftPX + leftPX) / div;
lcy1 = (pMinus1.leftPY + leftPY) / div;
rcx1 = (pMinus1.rightPX + rightPX) / div;
rcy1 = (pMinus1.rightPY + rightPY) / div;
// left and right points of next particle
lcx2 = (pPlus1.leftPX + leftPX) / div;
lcy2 = (pPlus1.leftPY + leftPY) / div;
rcx2 = (pPlus1.rightPX + rightPX) / div;
rcy2 = (pPlus1.rightPY + rightPY) / div;
}
}
// and click "save" when your done
//smoke ribbon
//
//Developed by sacculi based on code from zenbullets
//
// Dec 2008
// http://www.abandonedart.org
// http://www.zenbullets.com
//
// with lots of thanks to Erik Natzke (obviously)
// http://jot.eriknatzke.com/
//
// and James Alliban, who saved me the job of doing the conversion
// http://jamesalliban.wordpress.com/2008/12/04/2d-ribbons/
//
//
// This work is licensed under a Creative Commons 3.0 License.
// (Attribution - NonCommerical - ShareAlike)
//
// This basically means, you are free to use it as long as you:
// 1. give http://www.zenbullets.com a credit
// 2. dont use it for commercial gain
// 3. share anything you create with it in the same way I have
//
//Thanks zen bullets! (Matt Pearson) from sacculi (Will Pearson)
//================================= global vars
int _numRibbons = 3; //6
int _numParticles = 10; //40
float _randomness = .3;
RibbonManager ribbonManager;
float _a, _b, _centx, _centy, _x, _y;
float _ribbon1x, _ribbon1y, _ribbon2x, _ribbon2y, _ribbon3x, _ribbon3y;
float _noiseoff;
int _angle;
//================================= init
void setup() {
size(800,600);
background(255);
clearBackground();
//the original ribbon here...
_centx = (width / 2);
_centy = (height / 2);
//the other 3 suspects
//_ribbon1x = 0;
// _ribbon1y = height;
//_ribbon2x = width;
//_ribbon2y = height;
//_ribbon3x = width;
// _ribbon3y = 0;
restart();
}
void restart() {
_noiseoff = random(1);
_angle = 1;
_a = 3.5;
_b = _a + (noise(_noiseoff) * 1) - 0.5;
ribbonManager = new RibbonManager(_numRibbons, _numParticles, _randomness);
ribbonManager.setRadiusMax(40); // default = 8
ribbonManager.setRadiusDivide(2); // default = 10
ribbonManager.setGravity(-0.09); // default = .03
ribbonManager.setFriction(1.1); // default = 1.1
ribbonManager.setMaxDistance(40); // default = 40
ribbonManager.setDrag(2.5); // default = 2
ribbonManager.setDragFlare(.015); // default = .008
}
void clearBackground() {
background(0);
}
//================================= frame loop
void draw() {
clearBackground();
float newx = sin(_a + radians(_angle) + PI / 2) * _centx;
float newy = sin(_b + radians(_angle)) * _centy;
_angle = int(random(360));
_noiseoff += 0.05;
_b = (noise(_noiseoff) * 8) +1;
_a = _b;
translate(_centx, _centy);
scale(5);
ribbonManager.update(newx* 0.1, newy*0.1);
rotate(20);
ribbonManager.update(newx* 0.1, newy*0.1);
rotate(20);
ribbonManager.update(newx* 0.1, newy*0.1);
rotate(20);
ribbonManager.update(newx* 0.1, newy*0.1);
rotate(20);
ribbonManager.update(newx* 0.1, newy*0.1);
/*
translate(_ribbon1x, _ribbon1y);
ribbonManager.update(newx* 0.1, newy*0.1);
translate(_ribbon2x, _ribbon2y);
ribbonManager.update(newx* 0.1, newy*0.1);
translate(_ribbon3x, _ribbon3y);
ribbonManager.update(newx* 0.1, newy*0.1);
*/
}
//================================= interaction
void mousePressed() {
}
//================================= objects
// modified from original code by http://jamesalliban.wordpress.com/
//======== manager
class RibbonManager {
// PImage img;
int _numRibbons;
int _numParticles;
float _randomness;
Ribbon[] ribbons;
/* Ribbon[] ribbons1;
Ribbon[] ribbons2;
Ribbon[] ribbons3; */ // ribbon array
RibbonManager(int _numRibbons, int _numParticles, float _randomness) {
this._numRibbons = _numRibbons;
this._numParticles = _numParticles;
this._randomness = _randomness;
init();
}
void init() {
addRibbon();
}
void addRibbon() {
ribbons = new Ribbon[_numRibbons];
/*ribbons1 = new Ribbon[_numRibbons];
ribbons2 = new Ribbon[_numRibbons];
ribbons3 = new Ribbon[_numRibbons];*/
for (int i = 0; i < _numRibbons; i++) {
color ribbonColour = color(random(255), ((40/_numRibbons) * i) ) ;
ribbons[i] = new Ribbon(_numParticles, ribbonColour, _randomness);
/* ribbons1[i] = new Ribbon(_numParticles, ribbonColour, _randomness);
ribbons2[i] = new Ribbon(_numParticles, ribbonColour, _randomness);
ribbons3[i] = new Ribbon(_numParticles, ribbonColour, _randomness);*/
}
}
void update(float currX, float currY) {
for (int i = 0; i < _numRibbons; i++)
{
float randX = currX;
float randY = currY;
ribbons[i].update(randX, randY);
/* ribbons1[i].update(randX, randY);
ribbons2[i].update(randX, randY);
ribbons3[i].update(randX, randY);*/
}
}
void setRadiusMax(float value) {
for (int i = 0; i < _numRibbons; i++) {
ribbons[i].radiusMax = value;
}
}
void setRadiusDivide(float value) {
for (int i = 0; i < _numRibbons; i++) {
ribbons[i].radiusDivide = value;
}
}
void setGravity(float value) {
for (int i = 0; i < _numRibbons; i++) {
ribbons[i].gravity = value;
}
}
void setFriction(float value) {
for (int i = 0; i < _numRibbons; i++) {
ribbons[i].friction = value;
}
}
void setMaxDistance(int value) {
for (int i = 0; i < _numRibbons; i++) {
ribbons[i].maxDistance = value;
}
}
void setDrag(float value) {
for (int i = 0; i < _numRibbons; i++) {
ribbons[i].drag = value;
}
}
void setDragFlare(float value) {
for (int i = 0; i < _numRibbons; i++) {
ribbons[i].dragFlare = value;
}
}
}
//======== ribbon
class Ribbon {
int _numRibbons;
float _randomness;
int _numParticles; // length of the Particle Array (max number of points)
int particlesAssigned = 0; // current amount of particles currently in the Particle array
float radiusMax = 16; // maximum width of ribbon
float radiusDivide = 30; // distance between current and next point / this = radius for first half of the ribbon
float gravity = .06; // gravity applied to each particle
float friction = 1.1; // friction applied to the gravity of each particle
int maxDistance = 40; // if the distance between particles is larger than this the drag comes into effect
float drag = 2; // if distance goes above maxDistance - the points begin to grag. high numbers = less drag
float dragFlare = .008; // degree to which the drag makes the ribbon flare out
RibbonParticle[] particles; // particle array
color ribbonColor;
Ribbon(int _numParticles, color ribbonColor, float _randomness) {
this._numParticles = _numParticles;
this.ribbonColor = ribbonColor;
this._randomness = _randomness;
init();
}
void init() {
particles = new RibbonParticle[_numParticles];
}
void update(float randX, float randY) {
addParticle(randX, randY);
drawCurve();
}
void addParticle(float randX, float randY) {
if(particlesAssigned == _numParticles) {
for (int i = 1; i < _numParticles; i++) {
particles[i-1] = particles[i];
}
particles[_numParticles - 1] = new RibbonParticle(_randomness, this);
particles[_numParticles - 1].px = randX;
particles[_numParticles - 1].py = randY;
return;
}
else {
particles[particlesAssigned] = new RibbonParticle(_randomness, this);
particles[particlesAssigned].px = randX;
particles[particlesAssigned].py = randY;
++particlesAssigned;
}
if (particlesAssigned > _numParticles) ++particlesAssigned;
}
void drawCurve() {
smooth();
for (int i = 1; i < particlesAssigned - 1; i++) {
RibbonParticle p = particles[i];
p.calculateParticles(particles[i-1], particles[i+1], _numParticles, i);
}
fill(30);
for (int i = particlesAssigned - 3; i > 1 - 1; i--) {
RibbonParticle p = particles[i];
RibbonParticle pm1 = particles[i-1];
//fill(ribbonColor, 255);
fill(255, 255);
if (i < particlesAssigned-3) {
noStroke();
beginShape();
vertex(p.lcx2, p.lcy2);
bezierVertex(p.leftPX, p.leftPY, pm1.lcx2, pm1.lcy2, pm1.lcx2, pm1.lcy2);
vertex(pm1.rcx2, pm1.rcy2);
bezierVertex(p.rightPX, p.rightPY, p.rcx2, p.rcy2, p.rcx2, p.rcy2);
vertex(p.lcx2, p.lcy2);
endShape();
}
}
}
}
//======== particle
class RibbonParticle {
float px, py; // x and y position of particle (this is the bexier point)
float xSpeed, ySpeed = 0; // speed of the x and y positions
float cx1, cy1, cx2, cy2; // the avarage x and y positions between px and py and the points of the surrounding Particles
float leftPX, leftPY, rightPX, rightPY; // the x and y points of that determine the thickness of this segment
float lpx, lpy, rpx, rpy; // the x and y points of the outer bezier points
float lcx1, lcy1, lcx2, lcy2; // the avarage x and y positions between leftPX and leftPX and the left points of the surrounding Particles
float rcx1, rcy1, rcx2, rcy2; // the avarage x and y positions between rightPX and rightPX and the right points of the surrounding Particles
float radius; // thickness of current particle
float _randomness;
Ribbon ribbon;
RibbonParticle(float _randomness, Ribbon ribbon) {
this._randomness = _randomness;
this.ribbon = ribbon;
}
void calculateParticles(RibbonParticle pMinus1, RibbonParticle pPlus1, int particleMax, int i) {
float div = 2;
cx1 = (pMinus1.px + px) / div;
cy1 = (pMinus1.py + py) / div;
cx2 = (pPlus1.px + px) / div;
cy2 = (pPlus1.py + py) / div;
// calculate radians (direction of next point)
float dx = cx2 - cx1;
float dy = cy2 - cy1;
float pRadians = atan2(dy, dx);
float distance = sqrt(dx*dx + dy*dy);
if (distance > ribbon.maxDistance) {
float oldX = px;
float oldY = py;
px = px + ((ribbon.maxDistance/ribbon.drag) * cos(pRadians));
py = py + ((ribbon.maxDistance/ribbon.drag) * sin(pRadians));
xSpeed += (px - oldX) * ribbon.dragFlare;
ySpeed += (py - oldY) * ribbon.dragFlare;
}
ySpeed += ribbon.gravity;
xSpeed *= ribbon.friction;
ySpeed *= ribbon.friction;
px += xSpeed + random(.3);
py += ySpeed + random(.3);
float randX = ((_randomness / 2) - random(_randomness)) * distance;
float randY = ((_randomness / 2) - random(_randomness)) * distance;
px += randX;
py += randY;
//float radius = distance / 2;
//if (radius > radiusMax) radius = ribbon.radiusMax;
if (i > particleMax / 2) {
radius = distance / ribbon.radiusDivide;
}
else {
radius = pPlus1.radius * .9;
}
if (radius > ribbon.radiusMax) radius = ribbon.radiusMax;
if (i == particleMax - 2 || i == 1) {
if (radius > 1) radius = 1;
}
// calculate the positions of the particles relating to thickness
leftPX = px + cos(pRadians + (HALF_PI * 3)) * radius;
leftPY = py + sin(pRadians + (HALF_PI * 3)) * radius;
rightPX = px + cos(pRadians + HALF_PI) * radius;
rightPY = py + sin(pRadians + HALF_PI) * radius;
// left and right points of current particle
lpx = (pMinus1.lpx + lpx) / div;
lpy = (pMinus1.lpy + lpy) / div;
rpx = (pPlus1.rpx + rpx) / div;
rpy = (pPlus1.rpy + rpy) / div;
// left and right points of previous particle
lcx1 = (pMinus1.leftPX + leftPX) / div;
lcy1 = (pMinus1.leftPY + leftPY) / div;
rcx1 = (pMinus1.rightPX + rightPX) / div;
rcy1 = (pMinus1.rightPY + rightPY) / div;
// left and right points of next particle
lcx2 = (pPlus1.leftPX + leftPX) / div;
lcy2 = (pPlus1.leftPY + leftPY) / div;
rcx2 = (pPlus1.rightPX + rightPX) / div;
rcy2 = (pPlus1.rightPY + rightPY) / div;
}
}
info
submitted by: sevenspiral1views: 801
had been visuals for a dubstep act, a homage to @zenbullets as its a hack of something he did once in 100 Abandoned Artworks
comments
loading...
Add a comment: