home
|
featured sketches
|
gallery
|
write a sketch
|
community
|
Copy sketch
Printouts
// 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; } }
Sketches you submit on sketchPatch will be licensed under the
Creative Commons Attribution 3.0 Unported License
. If you upload code based on other people's work, please check the licence compatibility.
Click below to see an example
Get Started...
Copy this code into the text area to set up a basic sketch...
void setup() {
size(500,500);
}
void draw() {
background(200,30,90);
fill(20,40,150);
rect(100,100, 100,100);
}
Draw basic Shapes
Rectangle
Copy this code into the 'void draw ()' area of your code in the text area to draw a basic rectangle...
rect(100,100,100,100);
Triangle
Copy this code into the 'void draw ()' area of your code in the text area to draw a basic triangle...
triangle(30, 75, 58, 20, 86, 75);
Ellipse
Copy this code into the 'void draw ()' area of your code in the text area to draw a basic ellipse...
ellipse(56, 46, 55, 55);
Randomise
You can change how things look at random by using "random", all you need to do is specify the minimum and the maximum value you want.
Copy this code into the text area to randomly change the size and colour of your ellipse:
fill(random(0,255),20,200);
stroke(255,255,0);
ellipse(150, 150, random(10,150), 150);
Animate
You can animate your graphics by replacing numbers with "mouseX" , "mouseY" or "frameCount". In this example we change colors and shape size using the mouse:
background(20,30,mouseX);
fill(20,mouseY,150);
rect(100,100, 100,mouseX);
Drawing Tool
Copy this code into the 'void draw ()' area of your code to make a drawing tool...
fill(0,0,0);
noStroke();
ellipse(mouseX,mouseY, 2,2);
Then remove the line 'background();'
Repeat
You can repeat any piece of code by using a 'for loop'. A for loop changes a variable of a quantity you decide, until it reaches a number you want.
Example: add 10 each time to a variable called "i", until it gets to 200:
Copy this code into the text area to see a rectangle repeat across the sketch:
for (int i=0; i<200; i=i+10) {
rect(i,i, 100,100);
}
Ooops, found some glitches.
Write your sketch here
Check the Processing language
reference
(
most
of it works).
Need inspiration? Play with the examples in
the gallery
.
Title
Tags
Publish
(come on, let other people see your sketch!)
Your comments about the sketch
had been visuals for a dubstep act, a homage to @zenbullets as it's a hack of something he did once in 100 Abandoned Artworks