Skip to content

Instantly share code, notes, and snippets.

@dodo
Created November 24, 2011 21:04
Show Gist options
  • Save dodo/1392287 to your computer and use it in GitHub Desktop.
Save dodo/1392287 to your computer and use it in GitHub Desktop.
ledpainter for ledwall@c3d2 in processing
/**
* Circle Collision with Swapping Velocities
* by Ira Greenberg.
*
* Based on Keith Peter's Solution in
* Foundation Actionscript Animation: Making Things Move!
*//*
Ball[] balls = {
new Ball(100, 400, 20),
new Ball(200, 200, 50),
new Ball(700, 400, 80)
};
int ballcount = 3;
PVector[] vels = {
new PVector(4.15, -2.35),
new PVector(-4.15, 2.35),
new PVector(-2.65, .82)
};
String setsize(){
size(360, 360);
return P2D;
}
void init(PGraphics g) {
g.smooth();
g.noStroke();
}
void paint(PGraphics g) {
g.background(0);
g.fill(204);
for (int i=0; i< ballcount; i++){
balls[i].x += vels[i].x;
balls[i].y += vels[i].y;
g.ellipse(balls[i].x, balls[i].y, balls[i].r*2, balls[i].r*2);
checkBoundaryCollision(balls[i], vels[i]);
}
checkObjectCollision(balls, vels);
}
void checkObjectCollision(Ball[] b, PVector[] v){
// get distances between the balls components
PVector bVect = new PVector();
bVect.x = b[1].x - b[0].x;
bVect.y = b[1].y - b[0].y;
// calculate magnitude of the vector separating the balls
float bVectMag = sqrt(bVect.x * bVect.x + bVect.y * bVect.y);
if (bVectMag < b[0].r + b[1].r){
// get angle of bVect
float theta = atan2(bVect.y, bVect.x);
// precalculate trig values
float sine = sin(theta);
float cosine = cos(theta);
// bTemp will hold rotated ball positions. You
// just need to worry about bTemp[1] position
Ball[] bTemp = {
new Ball(), new Ball() };
// b[1]'s position is relative to b[0]'s
// so you can use the vector between them (bVect) as the
// reference point in the rotation expressions.
// bTemp[0].x and bTemp[0].y will initialize
// automatically to 0.0, which is what you want
// since b[1] will rotate around b[0]
bTemp[1].x = cosine * bVect.x + sine * bVect.y;
bTemp[1].y = cosine * bVect.y - sine * bVect.x;
// rotate Temporary velocities
PVector[] vTemp = {
new PVector(), new PVector() };
vTemp[0].x = cosine * v[0].x + sine * v[0].y;
vTemp[0].y = cosine * v[0].y - sine * v[0].x;
vTemp[1].x = cosine * v[1].x + sine * v[1].y;
vTemp[1].y = cosine * v[1].y - sine * v[1].x;
// Now that velocities are rotated, you can use 1D
// conservation of momentum equations to calculate
// the final velocity along the x-axis.
PVector[] vFinal = {
new PVector(), new PVector() };
// final rotated velocity for b[0]
vFinal[0].x = ((b[0].m - b[1].m) * vTemp[0].x + 2 * b[1].m *
vTemp[1].x) / (b[0].m + b[1].m);
vFinal[0].y = vTemp[0].y;
// final rotated velocity for b[0]
vFinal[1].x = ((b[1].m - b[0].m) * vTemp[1].x + 2 * b[0].m *
vTemp[0].x) / (b[0].m + b[1].m);
vFinal[1].y = vTemp[1].y;
// hack to avoid clumping
bTemp[0].x += vFinal[0].x;
bTemp[1].x += vFinal[1].x;
// Rotate ball positions and velocities back
// Reverse signs in trig expressions to rotate
// in the opposite direction
// rotate balls
Ball[] bFinal = {
new Ball(), new Ball() };
bFinal[0].x = cosine * bTemp[0].x - sine * bTemp[0].y;
bFinal[0].y = cosine * bTemp[0].y + sine * bTemp[0].x;
bFinal[1].x = cosine * bTemp[1].x - sine * bTemp[1].y;
bFinal[1].y = cosine * bTemp[1].y + sine * bTemp[1].x;
// update balls to screen position
b[1].x = b[0].x + bFinal[1].x;
b[1].y = b[0].y + bFinal[1].y;
b[0].x = b[0].x + bFinal[0].x;
b[0].y = b[0].y + bFinal[0].y;
// update velocities
v[0].x = cosine * vFinal[0].x - sine * vFinal[0].y;
v[0].y = cosine * vFinal[0].y + sine * vFinal[0].x;
v[1].x = cosine * vFinal[1].x - sine * vFinal[1].y;
v[1].y = cosine * vFinal[1].y + sine * vFinal[1].x;
}
}
void checkBoundaryCollision(Ball ball, PVector vel) {
if (ball.x > width-ball.r) {
ball.x = width-ball.r;
vel.x *= -1;
}
else if (ball.x < ball.r) {
ball.x = ball.r;
vel.x *= -1;
}
else if (ball.y > height-ball.r) {
ball.y = height-ball.r;
vel.y *= -1;
}
else if (ball.y < ball.r) {
ball.y = ball.r;
vel.y *= -1;
}
}
class Ball{
float x, y, r, m;
// default constructor
Ball() {
}
Ball(float x, float y, float r) {
this.x = x;
this.y = y;
this.r = r;
m = r*.1;
}
}
/**/
/**
a blooming tree by
<a href="http://www.local-guru.net/blog">Guru</a>
*//*
import java.util.List;
import java.util.ArrayList;
List branches;
String setsize() {
size(100,100);
println("click to reset");
return P2D;
}
PGraphics G;
void init(PGraphics g) {
G = g;
branches = new ArrayList();
Branch b = new Branch();
branches.add(b);
g.smooth();
g.noStroke();
g.background(0);
g.fill(123,0,0);
}
void paint(PGraphics g) {
List dead = new ArrayList();
for( int i = 0; i < branches.size(); i++ ) {
Branch b = ((Branch)branches.get(i));
if (!b.isDead()) {
b.draw(g);
if ( random(1, 100) > 97 ) {
branches.add(b.branch());
}
} else {
b.bloom(g);
dead.add(b);
}
}
for( int i = 0; i < dead.size(); i++ ) {
branches.remove( dead.get(i));
}
}
class Branch {
float s = 10;
float x = 50;
float y = 100;
float step = 3;
float a = 0;
float astep = 0.075;
public boolean isDead() {
return s < 0.1;
}
public Branch() {
}
public Branch( float x, float y, float s, float a, float step, float astep ) {
this.x = x;
this.y = y;
this.s = s;
this.a = a;
this.step = step;
this.astep = astep;
}
public Branch branch() {
return new Branch( x, y, s * 0.8, a, step *0.8, astep * -1 );
}
void draw(PGraphics g) {
g.ellipse( x, y, s, s );
step *= 0.98;
if ( random(1, 100) > ( cos(a) > 0 ? 80 : 90 ) ) {
astep *= -1;
}
a += astep;
y -= cos( a ) * step;
x += sin( a ) * step;
s *= 0.98;
}
void bloom(PGraphics g) {
g.fill(255, 40);
g.stroke(255,0,0, 10);
g.ellipse(x,y,9,9);
g.fill(0);
g.stroke(0);
}
}
void mousePressed() {
init(G);
}
/**/
/** color planets **//*
int dim=2; //dimensionality
int spikes = 10; // max size of spikes
int tot=100;
float speed = 10;
planet[] planets;
color[] pal={#244B49,#080E0D,#6D2506,#546916,#CC5A0D,#3C9A43,#B8B536,#C3D2C0};//@ flowers
String setsize() {
size(64,64);
println("click to reset");
return P2D;
}
PGraphics G;
void init(PGraphics g) {
G = g;
colorMode(HSB, 1);
g.background(0);
planets = new planet[tot];
for(int i = 0; i < tot; i++){
float[] p = new float[dim];
for(int d = 0; d < dim; d++)
p[d]= random(-g.width, g.width) / 2;
color c = pal[int(random(pal.length))];
planets[i]=new planet(p, color(hue(c),saturation(c),brightness(c), 0.1));
}
}
void paint(PGraphics g) {
if (frameCount%20 == 0) {
g.fill(0,10);
g.rect(0,0,width, height);
}
g.translate(g.width/2, g.height/2);
for(int i=0;i<tot;i++)
planets[i].step(g);
}
float colorDiff(color c1, color c2){
float a=hue(c1);
float b=hue(c2);
float ans1=b-a;
float ans2=a+b-1;
return random(0.4)-((abs(ans1)<abs(ans2))?ans1:ans2);}
class planet{
float[] p = new float[dim]; //current position
color c;
planet(float[] inP, color inC) {
p = inP;
c = inC*4;//color(red(inC)*2, green(inC)*2, blue(inC)*2);//inC;
}
void step(PGraphics g){
for(int i = 0; i < tot; i++){
if(planets[i] != this){
float insqrt = 0;
for(int d = 0; d < dim; d++)
insqrt += pow(planets[i].p[d] - p[d], 2);
float diff = colorDiff(planets[i].c, c);
for(int d = 0; d < dim; d++)
p[d] += speed * ((planets[i].p[d] - p[d]) * diff) / insqrt;
}
}
manifest(g);
}
void manifest(PGraphics g){
g.stroke(hue(c), random(0.5), 1, 0.1);
g.line(p[0], p[1], p[0] + random(-1,1), p[1] + random(-1,1));
g.stroke(hue(c), random(0.6), random(1), 0.08);
g.line(p[0], p[1], p[0] + random(-spikes,spikes), p[1] + random(-spikes,spikes));
g.stroke(c);
g.point(p[0], p[1]);
}
}
void mousePressed() {
init(G);
}
/**/
/*** creature ***//*
PImage fondo;
float inc = 0.0;
float posx=250;
float posy=250;
float angle3 = 0.0;
boolean food = false;
int foodiam=0;
int fadestroke;
float anglefood;
float a1 = 0.012;
float a2 = 0.001;
float a3 = 0.002;
float a4 = 0.003;
float a5 = 0.0025;
float a6 = 0.0034;
float a7 = 0.014;
float a8 = 0.0028;
float rot1, rot2, rot3, rot4, rot5, rot6, rot7, rot8;
float easing=0.004;
float targetY;
float targetX;
String setsize() {
size(100, 100);
return P2D;
}
void init(PGraphics g) {
targetX=random(width);
targetY=random(height);
g.stroke(0, 204);
g.smooth();
fondo = loadImage("fondo.png");
g.rectMode(CENTER);
}
void paint(PGraphics g) {
g.image (fondo,0,0);
//fill(255,90);
// rect(250,250,width,height);
//background(245,237,220);
g.fill(111,54,185);
//rect(0,0,width,height);
if (food == true) {
createFood(g, targetX, targetY);
// createFood(targetX-5, targetY-5);
// createFood(targetX-5, targetY+5);
}
if (dist(targetX,targetY,posx,posy) < 20) {
targetX=random(width);
targetY=random(height);
foodiam=10;
fadestroke=255;
food=true;
}
inc += 0.006;
float angle1 = sin(inc)/10.0 + sin (inc*4.5)/70.0;
float angle2 = cos(inc)/12.0 + cos (inc*4.5)/80.0;
angle3+=0.007;
//posx=250+cos(angle3)*100+sin(angle3)*100;
//posy=250+tan(cos(angle3))*100+cos(angle3)*25;
posx += (targetX-posx)*easing;
posy += (targetY-posy)*easing;
g.stroke(0, 204);
g.translate(posx,posy);
tail(g, 0, 24, angle1*4);
g.rotate(sin(rot1)+QUARTER_PI);
tail(g, 0, 21, angle1*2.7);
g.rotate(cos(rot2)+QUARTER_PI);
tail(g, 0, 18, angle2*5.5);
g.rotate(rot3+QUARTER_PI);
tail(g, 0, 17, angle1*3);
g.rotate(sin(rot4+QUARTER_PI));
tail(g, 0, 19, angle2*4.2);
g.rotate(atan(rot5)+QUARTER_PI);
tail(g, 0, 20, angle1*2.4);
g.rotate(sin(rot6)+QUARTER_PI);
tail(g, 0, 24, angle2*3);
g.rotate(cos(rot7)+QUARTER_PI);
tail(g, 0, 25, angle1*3.2);
rot1+=a1;
rot2+=a2;
rot3+=a3;
rot4+=a4;
rot5+=a5;
rot6+=a6;
rot7+=a7;
rot8+=a8;
g.filter(INVERT);
}
void tail(PGraphics g, int x, int units, float angle) {
g.pushMatrix();
g.translate(x, 0);
for (int i = units; i > 0; i--) {
g.strokeWeight(sqrt(i/6));
//g.line(-i,0,i,0);
g.fill(255);
g.ellipse(-i,0,2,2);
g.ellipse(i,0,2,2);
g.strokeWeight(i/1.7);
g.fill(111,54,185);
g.ellipse(0,0,sqrt(i),sqrt(i));
g.line(0,0,0,-8);
g.translate(0, -10);
g.rotate(angle);
}
g.popMatrix();
}
void mousePressed() {
//saveFrame("pulpo-###.png");
targetX=mouseX;
targetY=mouseY;
foodiam=10;
fadestroke=255;
food=true;
}
void createFood(PGraphics g, float locationX, float locationY) {
g.fill(0,255,0);
g.ellipse(locationX, locationY,3+abs(cos(anglefood)*3),3+abs(cos(anglefood)*3));
g.fill(0,255,0,10);
g.ellipse(locationX, locationY,abs(cos(anglefood)*2),abs(cos(anglefood)*2));
g.noFill();
g.stroke(0,255,0,80);
g.ellipse(locationX, locationY,10+abs(cos(anglefood+QUARTER_PI)*3),10+abs(cos(anglefood+QUARTER_PI)*3));
if (foodiam < 220) {
g.noFill();
g.stroke (0,fadestroke);
g.ellipse(locationX, locationY, foodiam,foodiam);
foodiam++;
fadestroke-=2;
}
anglefood+=map(dist(targetX,targetY,posx,posy),0,300,0.2,0.01);
}
/**/
/**
* Fire Cube demo effect
* by luis2048.
*
* A rotating wireframe cube with flames rising up the screen.
* The fire effect has been used quite often for oldskool demos.
* First you create a palette of 256 colors ranging from red to
* yellow (including black). For every frame, calculate each row
* of pixels based on the two rows below it: The value of each pixel,
* becomes the sum of the 3 pixels below it (one directly below, one
* to the left, and one to the right), and one pixel directly two
* rows below it. Then divide the sum so that the fire dies out as
* it rises.
*//*
// This will contain the pixels used to calculate the fire effect
int[][] fire;
// Flame colors
color[] palette;
float angle;
int[] calc1,calc2,calc3,calc4,calc5;
PGraphics gg;
String setsize() {
size(190, 190);
return P2D;
}
void init(PGraphics g){
// Create buffered image for 3d cube
gg = createGraphics(width, height, P3D);
calc1 = new int[width];
calc3 = new int[width];
calc4 = new int[width];
calc2 = new int[height];
calc5 = new int[height];
colorMode(HSB);
fire = new int[width][height];
palette = new color[255];
// Generate the palette
for(int x = 0; x < palette.length; x++) {
//Hue goes from 0 to 85: red to yellow
//Saturation is always the maximum: 255
//Lightness is 0..255 for x=0..128, and 255 for x=128..255
palette[x] = color(x/3, 255, constrain(x*3, 0, 255));
}
// Precalculate which pixel values to add during animation loop
// this speeds up the effect by 10fps
for (int x = 0; x < width; x++) {
calc1[x] = x % width;
calc3[x] = (x - 1 + width) % width;
calc4[x] = (x + 1) % width;
}
for(int y = 0; y < height; y++) {
calc2[y] = (y + 1) % height;
calc5[y] = (y + 2) % height;
}
}
void paint(PGraphics g) {
angle = angle + 0.05;
// Rotating wireframe cube
gg.beginDraw();
gg.lights();
gg.translate(width >> 1, height >> 1);
gg.rotateX(sin(angle/2));
gg.rotateY(cos(angle/2));
gg.background(0);
gg.stroke(128);
gg.strokeWeight(10);
gg.scale(25);
gg.fill(0);//gg.noFill();
gg.box(4);
gg.endDraw();
// Randomize the bottom row of the fire buffer
for(int x = 0; x < width; x++)
{
fire[x][height-1] = int(random(0,190)) ;
}
//g.image(gg, 0,0);
g.loadPixels();
//g.image(gg, 0,0);
int counter = 0;
// Do the fire calculations for every pixel, from top to bottom
for (int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
// Add pixel values around current pixel
fire[x][y] =
((fire[calc3[x]][calc2[y]]
+ fire[calc1[x]][calc2[y]]
+ fire[calc4[x]][calc2[y]]
+ fire[calc1[x]][calc5[y]]) << 5) / 129;
// Output everything to screen using our palette colors
g.pixels[counter] = palette[fire[x][y]];
// Extract the red value using right shift and bit mask
// equivalent of red(gg.pixels[x+y*w])
if ((gg.pixels[counter++] >> 16 & 0xFF) == 128) {
// Only map 3D cube 'lit' pixels onto fire array needed for next frame
fire[x][y] = 128;
}
}
}
g.updatePixels();
}
/**/
/**
* Get Line In
* by Damien Di Fede.
*
* This sketch demonstrates how to use the <code>getLineIn</code> method of
* <code>Minim</code>. This method returns an <code>AudioInput</code> object.
* An <code>AudioInput</code> represents a connection to the computer's current
* record source (usually the line-in) and is used to monitor audio coming
* from an external source. There are five versions of <code>getLineIn</code>:
* <pre>
* getLineIn()
* getLineIn(int type)
* getLineIn(int type, int bufferSize)
* getLineIn(int type, int bufferSize, float sampleRate)
* getLineIn(int type, int bufferSize, float sampleRate, int bitDepth)
* </pre>
* The value you can use for <code>type</code> is either <code>Minim.MONO</code>
* or <code>Minim.STEREO</code>. <code>bufferSize</code> specifies how large
* you want the sample buffer to be, <code>sampleRate</code> specifies the
* sample rate you want to monitor at, and <code>bitDepth</code> specifies what
* bit depth you want to monitor at. <code>type</code> defaults to <code>Minim.STEREO</code>,
* <code>bufferSize</code> defaults to 1024, <code>sampleRate</code> defaults to
* 44100, and <code>bitDepth</code> defaults to 16. If an <code>AudioInput</code>
* cannot be created with the properties you request, <code>Minim</code> will report
* an error and return <code>null</code>.
*
* When you run your sketch as an applet you will need to sign it in order to get an input.
*
* Before you exit your sketch make sure you call the <code>close</code> method
* of any <code>AudioInput</code>'s you have received from <code>getLineIn</code>.
*/
import ddf.minim.analysis.*;
import ddf.minim.*;
Minim minim;
AudioInput in;
String setsize() {
size(256, 265);
return P2D;
}
FFT fft;
void init(PGraphics g)
{
g.strokeWeight(1);
minim = new Minim(this);
minim.debugOn();
// get a line in from Minim, default bit depth is 16
in = minim.getLineIn(Minim.STEREO, 2048);
fft = new FFT(in.bufferSize(), in.sampleRate());
}
void paint(PGraphics g)
{
g.noStroke();
g.fill(0,200);
g.rect(0,0,width,height);
//g.stroke(255);
// perform a forward FFT on the samples in jingle's left buffer
// note that if jingle were a MONO file, this would be the same as using jingle.right or jingle.left
fft.forward(in.mix);
for(int i = 0; i < fft.specSize(); i++)
{
// draw the line for frequency band i, scaling it by 4 so we can see it a bit better
float y = log(i*0.02)*2;
float x = i*0.3;
float v = 12;
int cr=0, cg=0, cb=0;
cr -= fft.getBand(round(v*0.1)); cg -= fft.getBand(round(v*0.3)); cb += fft.getBand(round(v*0.1));
v = 23;
cr += fft.getBand(round(v*0.08)); cg -= fft.getBand(round(v*0.05)); cb += fft.getBand(round(v*0.02));
v = 36;
cr += fft.getBand(round(v*0.3)); cg += fft.getBand(round(v*0.05)); cb -= fft.getBand(round(v*0.02));
v = 26;
cr -= fft.getBand(round(v*0.2)); cg += fft.getBand(round(v*0.05)); cb -= fft.getBand(round(v*0.02));
int c = color(round(cr*4),round(cg*4),round(cb*4));
g.stroke(c); g.fill(c);
g.line(x, height*0.5 - fft.getBand(round(y))*0.5, x, height*0.5 + fft.getBand(round(y))*0.5);
}
//g.fill(255);
}
/*void paint(PGraphics g)
{
g.background(0);
g.noStroke();
// draw the waveforms
for(int i = 0; i < in.bufferSize() - 1; i++)
{
g.stroke(255,0,0);
g.line(i, 50 + in.left.get(i)*20, i+1, 50 + in.left.get(i+1)*20);
g.stroke(0,0,255);
g.line(i, 150 + in.right.get(i)*50, i+1, 150 + in.right.get(i+1)*50);
}
}*//*
void stop()
{
// always close Minim audio classes when you are done with them
in.close();
minim.stop();
super.stop();
}
/**/
/*** Pentawall HD 16p ***/
/*********** hexadecimal **/
import processing.net.*;
Client wall;
PGraphics pg, g;
int W = 15, H = 16;
float last_time;float old_frameRate;PFont font; void initfont() {font=loadFont("LiberationMono-Bold-12.vlw");last_time = millis();}
void setup()
{
wall = new Client(this, "172.22.99.6", 1338);
frameRate(21);
initfont();
smooth();
pg = createGraphics(W, H, P2D);
String s = setsize();
g = createGraphics(width, height, s);
g.beginDraw();
//g.rectMode(CENTER);
g.smooth();
g.noStroke();
init(g);
g.endDraw();
wall.write("0402\r\n020000000000\r\n");
}
void draw()
{
g.beginDraw();
paint(g);
g.endDraw();
image(g, 0,0);
pg.beginDraw();
pg.background(color(255,0,0));
if (true) {//(wall != null) {
pg.background(0);
pg.image(g, 0,0, W, H);
//pg.filter(BLUR, 0.6);
}
pg.endDraw();
image(pg, 0, 0);
drawFPS();
if (frameCount%50==0) {
wall.write("0402\r\n");
}
if (true){//frameCount%1==0) {
String s, data = "";
pg.loadPixels();
for(int y=0;y<H;y++) for(int x=0;x<W;x++) data += hex(pg.pixels[y*(W-1)+x], 6);
if (wall != null) wall.write("03"+data+"\r\n");
//println(data.length());
//println(data);
}
}
void drawFPS() {
textFont(font);
textAlign(RIGHT,TOP);
fill(0); text(old_frameRate,width-1,1);
old_frameRate = frameRate;
fill(200); text(old_frameRate,width-1,1);
}
/**
* Letter K
* by Peter Cho.
*
* Move the mouse across the screen to fold the "K".
*//*
color backgroundColor;
color foregroundColor;
color foregroundColor2;
float px, py;
float pfx, pfy;
float pv2, pvx, pvy;
float pa2, pax, pay;
float pMass, pDrag;
String setsize() {
size(220, 220);
return P3D;
}
void init(PGraphics g) {
g.noStroke();
backgroundColor = color(134, 144, 154);
foregroundColor = color(235, 235, 30);
foregroundColor2 = color(240, 130, 20);
initParticle(0.6, 0.9, width/2, height/2);
}
void paint(PGraphics g) {
g.background(backgroundColor);
g.pushMatrix();
iterateParticle(0.15*(-px+mouseX), 0.15*(-py+(height-mouseY)));
g.translate(width/2, height/2, 0);
g.fill(foregroundColor);
drawK(g);
g.pushMatrix();
g.translate(0, 0, 1);
g.translate(0.75 * (px-width/2), -0.75 * (py-height/2), 0);
g.translate(0.75 * (px-width/2), -0.75 * (py-height/2), 0);
g.rotateZ(atan2(-(py-height/2), (px-width/2)) + PI/2);
g.rotateX(PI);
g.rotateZ(-(atan2(-(py-height/2), (px-width/2)) + PI/2));
g.fill(foregroundColor2);
drawK(g);
g.popMatrix();
g.translate(0.75 * (px-width/2), -0.75 * (py-height/2), 2);
g.rotateZ(atan2(-(py-height/2), (px-width/2)) + PI/2);
g.fill(backgroundColor);
g.beginShape(QUADS);
g.vertex(-640, 0);
g.vertex( 640, 0);
g.vertex( 640, -360);
g.vertex(-640, -360);
g.endShape();
g.popMatrix();
}
void initParticle(float _mass, float _drag, float ox, float oy) {
px = ox;
py = oy;
pv2 = 0.0;
pvx = 0.0;
pvy = 0.0;
pa2 = 0.0;
pax = 0.0;
pay = 0.0;
pMass = _mass;
pDrag = _drag;
}
void iterateParticle(float fkx, float fky) {
// iterate for a single force acting on the particle
pfx = fkx;
pfy = fky;
pa2 = pfx*pfx + pfy*pfy;
if (pa2 < 0.0000001) {
return;
}
pax = pfx/pMass;
pay = pfy/pMass;
pvx += pax;
pvy += pay;
pv2 = pvx*pvx + pvy*pvy;
if (pv2 < 0.0000001) {
return;
}
pvx *= (1.0 - pDrag);
pvy *= (1.0 - pDrag);
px += pvx;
py += pvy;
}
void drawK(PGraphics g) {
g.pushMatrix();
g.scale(1.5);
g.translate(-63, 71);
g.beginShape(QUADS);
g.vertex(0, 0, 0);
g.vertex(0, -142.7979, 0);
g.vertex(37.1992, -142.7979, 0);
g.vertex(37.1992, 0, 0);
g.vertex(37.1992, -87.9990, 0);
g.vertex(84.1987, -142.7979, 0);
g.vertex(130.3979, -142.7979, 0);
g.vertex(37.1992, -43.999, 0);
g.vertex(77.5986-.2, -86.5986-.3, 0);
g.vertex(136.998, 0, 0);
g.vertex(90.7988, 0, 0);
g.vertex(52.3994-.2, -59.999-.3, 0);
g.endShape();
//translate(63, -71);
g.popMatrix();
}
/**/
/**
* Puff
* by Ira Greenberg.
*
* Series of ellipses simulating a multi-segmented
* organism, utilizing a follow the leader algorithm.
* Collision detection occurs on the organism's head,
* controlling overall direction, and on the individual
* body segments, controlling body shape and jitter.
*//*
// For puff head
float headX;
float headY;
float speedX = .7;
float speedY = .9;
// For puff body
int cells = 1000;
float[]px= new float[cells];
float[]py= new float[cells];
float[]radiiX = new float[cells];
float[]radiiY = new float[cells];
float[]angle = new float[cells];
float[]frequency = new float[cells];
float[]cellRadius = new float[cells];
String setsize() {
size(120, 120);
return P2D;
}
void init(PGraphics g){
// Begin in the center
headX = width/2;
headY = height/2;
// Fill body arrays
for (int i=0; i< cells; i++){
radiiX[i] = random(-7, 7);
radiiY[i] = random(-4, 4);
frequency[i]= random(-9, 9);
cellRadius[i] = random(16, 30);
}
}
void paint(PGraphics g){
//g.background(0);
g.fill(0,23);
g.rect(0,0,g.width,g.height);
g.noStroke();
g.fill(255, 255, 255, 5);
// Follow the leader
for (int i =0; i< cells; i++){
if (i==0){
px[i] = headX+sin(radians(angle[i]))*radiiX[i];
py[i] = headY+cos(radians(angle[i]))*radiiY[i];
}
else{
px[i] = px[i-1]+cos(radians(angle[i]))*radiiX[i];
py[i] = py[i-1]+sin(radians(angle[i]))*radiiY[i];
// Check collision of body
if (px[i] >= width-cellRadius[i]/2 || px[i] <= cellRadius[i]/2){
radiiX[i]*=-1;
cellRadius[i] = random(1, 40);
frequency[i]= random(-13, 13);
}
if (py[i] >= height-cellRadius[i]/2 || py[i] <= cellRadius[i]/2){
radiiY[i]*=-1;
cellRadius[i] = random(1, 40);
frequency[i]= random(-9, 9);
}
}
// Draw puff
g.fill(i,169,23,5);
g.ellipse(px[i], py[i], cellRadius[i], cellRadius[i]);
// Set speed of body
angle[i]+=frequency[i];
}
// Set velocity of head
headX+=speedX;
headY+=speedY;
// Check boundary collision of head
if (headX >= width-cellRadius[0]/2 || headX <=cellRadius[0]/2){
speedX*=-1;
}
if (headY >= height-cellRadius[0]/2 || headY <= cellRadius[0]/2){
speedY*=-1;
}
}
/**/
/*** mouse pointer ***/
/*
int omx, omy;
float s;
String setsize() {
size(640, 640);
println("move mouse");
return P2D;
}
void init(PGraphics g) {
g.background(0);
g.ellipseMode(CENTER);
g.noStroke();
g.smooth();
omx = mouseX;
omy = mouseY;
}
void paint(PGraphics g) {
g.fill(0, 10);
g.rect(0,0,g.width,g.height);
g.fill(200);
g.ellipse(omx, omy, s, s);
s -= 50;
if (s < 100) s = 100;
g.fill(200,0,0);
g.ellipse(mouseX, mouseY, s-1, s-1);
omx = mouseX;
omy = mouseY;
}
void mousePressed () {
s = 500;
}
/**/
/**
* Plasma Demo Effect
* by luis2048.
*
* Cycles of changing colours warped to give an illusion
* of liquid, organic movement.Colors are the sum of sine
* functions and various formulas. Based on formula by Robert Klep.
*//*
int pixelSize=2;
PGraphics gg;
String setsize() {
size(360, 360);
return P2D;
}
void init(PGraphics g){
// Create buffered image for plasma effect
gg = createGraphics(160, 90, P2D);
colorMode(HSB);
g.noSmooth();
}
void paint(PGraphics g)
{
float xc = 25;
// Enable this to control the speed of animation regardless of CPU power
// int timeDisplacement = millis()/30;
// This runs plasma as fast as your computer can handle
int timeDisplacement = frameCount;
// No need to do this math for every pixel
float calculation1 = sin( radians(timeDisplacement * 0.61655617));
float calculation2 = sin( radians(timeDisplacement * -3.6352262));
// Output into a buffered image for reuse
gg.beginDraw();
gg.loadPixels();
// Plasma algorithm
for (int x = 0; x < gg.width; x++, xc += pixelSize)
{
float yc = 25;
float s1 = 128 + 128 * sin(radians(xc) * calculation1 );
for (int y = 0; y < gg.height; y++, yc += pixelSize)
{
float s2 = 128 + 128 * sin(radians(yc) * calculation2 );
float s3 = 128 + 128 * sin(radians((xc + yc + timeDisplacement * 5) / 2));
float s = (s1+ s2 + s3) / 3;
gg.pixels[x+y*gg.width] = color(s, 255 - s / 2.0, 255);
}
}
gg.updatePixels();
gg.endDraw();
// display the results
g.image(gg,0,0,g.width,g.height);
}
/**/
// Gravity Swarm
// Claudio Gonzales, March 2010
// Albuquerque, New Mexico
/*
particle[] Z = new particle[8000];
float colour = random(1);
boolean tracer = false;
int depth;
String setsize() {
size(200,200);
return P2D;
}
void init(PGraphics g) {
g.smooth();
depth = width;
g.background(0);
//frameRate(25);
float n = 100;
float px, py, pz;
float m, v, theta, phi;
for(int k = 0; k < n; k++) {
px = random(width);
py = random(height);
pz = random(depth);
m = random(50);
for(int i = int((Z.length-1000)*k/n); i < int((Z.length-1000)*(k+1)/n); i++) {
v = sq(random(sqrt(m)));
theta = random(TWO_PI);
phi = random(TWO_PI);
Z[i] = new particle( px+v*cos(phi)*cos(theta), py+v*cos(phi)*sin(theta), pz+v*sin(phi), 0, 0, 0, 1 );
}
}
px = width/2;
py = height/2;
for(int i = Z.length-1000; i < Z.length; i++) {
pz = random(depth);
v = sq(random(sqrt(width/4)));
theta = random(TWO_PI);
Z[i] = new particle( px+v*cos(theta), py+v*sin(theta), pz, 0, 0, 0, 1 );
}
//for(int i = 0; i < Z.length; i++) {
// r = i/float(Z.length);
// Z[i] = new particle( random(width), r*height, depth/2, 0, 0, 0, 1 );
//}
//frameRate(60);
}
void paint(PGraphics g) {
g.colorMode(RGB,255);
float r;
if( !tracer ) {
g.background(0);
}
else {
g.fill(0,10);
g.rect(0,0,width,height);
}
g.filter(INVERT);
for(int i = 0; i < Z.length; i++) {
if( mousePressed && mouseButton == LEFT ) {
Z[i].gravitate( new particle( mouseX, mouseY, depth/2, 0, 0, 0, 0.75 ) );
}
else if( mousePressed && mouseButton == RIGHT ) {
Z[i].repel( new particle( mouseX, mouseY, depth/2, 0, 0, 0, 1 ) );
}
else {
Z[i].deteriorate();
}
Z[i].update();
r = float(i)/Z.length;
g.colorMode(HSB,1);
if( Z[i].magnitude/100 < 0.1 ) {
g.stroke( colour, pow(r,0.1), 0.9*sqrt(1-r), Z[i].magnitude/100+abs(Z[i].z/depth)*0.05 );
}
else {
g.stroke( colour, pow(r,0.1), 0.9*sqrt(1-r), 0.1+abs(Z[i].z/depth)*0.05 );
}
Z[i].display(g);
}
colour+=random(0.01);
colour = colour%1;
g.filter(INVERT);
}
void keyPressed() {
if( key == ' ' ) {
float r, choice = random(1);
for(int i = 0; i < Z.length; i++) {
r = i/float(Z.length);
if( choice > 0.8 ) {
// Slice
Z[i].reset( r*width, r*height, random(depth), 0, 0, 0, 1 );
}
else if( choice > 0.6 ) {
// Plane
Z[i].reset( random(width), r*height, depth/2, 0, 0, 0, 1 );
}
else if( choice > 0.4 ) {
// X
if( r < 0.5 )
Z[i].reset( (1-2*r)*width, 2*r*height, 2*r*depth, 0, 0, 0, 1 );
else
Z[i].reset( (1-(2*r-1))*width, (1-(2*r-1))*height, (2*r-1)*depth, 0, 0, 0, 1 );
}
else if( choice > 0.2 ) {
// Smooth Curve
Z[i].reset( (1-r)*width, sqrt(r)*height, r*depth, 0, 0, 0, 1 );
}
else {
// Swirl
Z[i].reset( height/2+r*cos(r*10*PI)*height/2, height/2+r*sin(r*10*PI)*height/2, r*depth, 0, 0, 0, 1 );
}
}
}
else if( key == ENTER ) {
tracer = !tracer;
}
}
class particle {
float x;
float y;
float z;
float px;
float py;
float magnitude;
float theta;
float phi;
float mass;
particle( float dx, float dy, float dz, float V, float T, float P, float M ) {
x = dx;
y = dy;
z = dz;
px = dx;
py = dy;
magnitude = V;
theta = T;
phi = P;
mass = M;
}
void reset ( float dx, float dy, float dz, float V, float T, float P, float M ) {
x = dx;
y = dy;
z = dz;
px = dx;
py = dy;
magnitude = V;
theta = T;
phi = P;
mass = M;
}
void gravitate( particle C ) {
float dx, dy, dz;
float F, t, p;
if( sq( x - C.x ) + sq( y - C.y ) + sq( z - C.z ) != 0 ) {
F = mass * C.mass;
// magnitude
dx = ( mass * x + C.mass * C.x ) / ( mass + C.mass );
dy = ( mass * y + C.mass * C.y ) / ( mass + C.mass );
dz = ( mass * z + C.mass * C.z ) / ( mass + C.mass );
// find point to which particle is being attracted (dx,dy,dz)
t = atan2( dy-y, dx-x ); // find yaw angle
p = atan2( dz-z, sqrt( sq(dy-y) + sq(dx-x) ) ) ; // find depth angle
dx = F * cos(p) * cos(t);
dy = F * cos(p) * sin(t);
dz = F * sin(p);
dx += magnitude * cos(phi) * cos(theta);
dy += magnitude * cos(phi) * sin(theta);
dz += magnitude * sin(phi);
magnitude = sqrt( sq(dx) + sq(dy) + sq(dz) );
theta = atan2( dy, dx );
phi = atan2( dz, sqrt( sq(dx) + sq(dy) ) );
}
}
void repel( particle C ) {
float dx, dy, dz;
float F, t, p;
if( sq( x - C.x ) + sq( y - C.y ) + sq( z - C.z ) != 0 ) {
F = mass * C.mass;
// magnitude
dx = ( mass * x + C.mass * C.x ) / ( mass + C.mass );
dy = ( mass * y + C.mass * C.y ) / ( mass + C.mass );
dz = ( mass * z + C.mass * C.z ) / ( mass + C.mass );
// find point to which particle is being attracted (dx,dy,dz)
t = atan2( y-dy, x-dx ); // find yaw angle
p = atan2( z-dz, sqrt( sq(dy-y) + sq(dx-x) ) ) ; // find depth angle
dx = F * cos(p) * cos(t);
dy = F * cos(p) * sin(t);
dz = F * sin(p);
dx += magnitude * cos(phi) * cos(theta);
dy += magnitude * cos(phi) * sin(theta);
dz += magnitude * sin(phi);
magnitude = sqrt( sq(dx) + sq(dy) + sq(dz) );
theta = atan2( dy, dx );
phi = atan2( dz, sqrt( sq(dx) + sq(dy) ) );
}
}
void deteriorate() {
magnitude *= 0.925;
}
void update() {
x += magnitude * cos(phi) * cos(theta);
y += magnitude * cos(phi) * sin(theta);
z += magnitude * sin(phi);
}
void display(PGraphics g) {
g.line(px,py,x,y);
px = x;
py = y;
}
}
/**/
/*
float maxrots = .4;
int totLines = 1000;
Line[] lines = new Line[totLines];
String setsize(){
size(640,360);
return P3D;
}
void init(PGraphics g) {
g.colorMode(HSB,1);
for(int i = 0; i < totLines; i++)
lines[i] = randomLine();
g.camera(0, 0, (height<width?height:width), 0, 0, 0, 0, 1, 0);
g.noStroke();
}
Line randomLine() {
return new Line(randomPoint(),randomPoint());
}
float e = 100;
Point randomPoint() {
return new Point(random(-e,e),random(-e,e),random(-e,e));
}
float ti = 0;
void paint(PGraphics g) {
g.background(1);
ti+=0.01;
g.rotateX(-ti);
g.rotateY(-ti/2);
g.rotateZ(-ti/3);
Point c = new Point(sin(ti)*width,cos(ti)*height,0);
for(int i = 0; i < totLines; i++)
nearestPoint(lines[i],c).render(g);
g.filter(INVERT);
}
float interp(float low, float high, float t) {
return ((high - low) * t) + low;
}
Point nearestPoint(Line line, Point C) {
Point A = line.a;
Point B = line.b;
float t1 = A.x*A.x;
float t2 = A.y*A.y;
float t3 = A.z*A.z;
float t4 = B.x*A.x;
float t7 = B.y*A.y;
float t10 = B.z*A.z;
float t13 = -t1-t2-t3+t4-B.x*C.x+A.x*C.x+t7-B.y*C.y+A.y*C.y+t10-B.z*C.z+A.z*C.z;
float t14 = B.x*B.x;
float t15 = B.y*B.y;
float t16 = B.z*B.z;
float t23 = -t13/(t14+t1+t15+t2+t16+t3-2.0*t4-2.0*t7-2.0*t10);
return line.pointAt(t23);
}
class Line {
Point a, b;
Line(Point a, Point b) {
this.a = a;
this.b = b;
}
Point pointAt(float t) {
float x = interp(a.x, b.x, t);
float y = interp(a.y, b.y, t);
float z = interp(a.z, b.z, t);
return new Point(x, y, z);
}
void render(PGraphics g) {
g.line(a.x,a.y,a.z,b.x,b.y,b.z);
}
}
class Point {
float x, y, z;
float rotx, roty, rotz;
float rotsx, rotsy, rotsz;
Point(float x, float y, float z) {
this.x = x;
this.y = y;
this.z = z;
rotx = 0;
roty = 0;
rotz = 0;
rotsx = random(-maxrots,maxrots);
rotsy = random(-maxrots,maxrots);
rotsz = random(-maxrots,maxrots);
}
void render(PGraphics g) {
rotx += rotsx;
roty += rotsy;
rotz += rotsz;
g.pushMatrix();
g.translate(x,y,z);
g.rotateX(rotx);
g.rotateY(roty);
g.fill(0, 1);
g.rect(-2,-2,4,4);
g.fill(0, .2);
g.rect(-8,-8,16,16);
g.fill(0, .1);
g.rect(-16,-16,32,32);
g.popMatrix();
}
}
/**/
/**
* Smoke
* by Glen Murphy.
*
* Drag the mouse across the image to move the particles.
* Code has not been optimised and will run fairly slowly.
*//*
int res = 2;
int penSize = 30;
int lwidth;
int lheight;
int pnum = 30000;
vsquare[][] v;
vbuffer[][] vbuf;
particle[] p;
int pcount = 0;
int mouseXvel = 0;
int mouseYvel = 0;
int randomGust = 0;
int randomGustMax;
float randomGustX;
float randomGustY;
float randomGustSize;
float randomGustXvel;
float randomGustYvel;
String setsize() {
size(100, 100);
println("click to schubs");
return P2D;
}
void init(PGraphics g)
{
lwidth = width/res;
lheight = height/res;
v = new vsquare[lwidth+1][lheight+1];
vbuf = new vbuffer[lwidth+1][lheight+1];
p = new particle[pnum];
g.noStroke();
for(int i = 0; i < pnum; i++) {
p[i] = new particle(random(width/2-20,width/2+20),random(height-20,height));
}
for(int i = 0; i <= lwidth; i++) {
for(int u = 0; u <= lheight; u++) {
v[i][u] = new vsquare(i*res,u*res);
vbuf[i][u] = new vbuffer(i*res,u*res);
}
}
}
void paint(PGraphics g)
{
g.background(0);
int axvel = mouseX-pmouseX;
int ayvel = mouseY-pmouseY;
mouseXvel = (axvel != mouseXvel) ? axvel : 0;
mouseYvel = (ayvel != mouseYvel) ? ayvel : 0;
if(randomGust <= 0) {
if(random(0,10)<1) {
randomGustMax = (int)random(5,12);
randomGust = randomGustMax;
randomGustX = random(0,width);
randomGustY = random(0,height-10);
randomGustSize = random(0,50);
if(randomGustX > width/2) {
randomGustXvel = random(-8,0);
} else {
randomGustXvel = random(0,8);
}
randomGustYvel = random(-2,1);
}
randomGust--;
}
for(int i = 0; i < lwidth; i++) {
for(int u = 0; u < lheight; u++) {
vbuf[i][u].updatebuf(i,u);
v[i][u].col = 0;
}
}
for(int i = 0; i < pnum-1; i++) {
p[i].updatepos();
}
for(int i = 0; i < lwidth; i++) {
for(int u = 0; u < lheight; u++) {
v[i][u].addbuffer(i, u);
v[i][u].updatevels(mouseXvel, mouseYvel);
v[i][u].display(g, i, u);
}
}
randomGust = 0;
}
class particle
{
float x;
float y;
float xvel;
float yvel;
float temp;
int pos;
particle(float xIn, float yIn) {
x = xIn;
y = yIn;
}
void reposition() {
x = width/2+random(-20,20);
y = random(height-10,height);
xvel = random(-1,1);
yvel = random(-1,1);
}
void updatepos() {
int vi = (int)(x/res);
int vu = (int)(y/res);
if(vi > 0 && vi < lwidth && vu > 0 && vu < lheight) {
v[vi][vu].addcolour(2);
float ax = (x%res)/res;
float ay = (y%res)/res;
xvel += (1-ax)*v[vi][vu].xvel*0.05;
yvel += (1-ay)*v[vi][vu].yvel*0.05;
xvel += ax*v[vi+1][vu].xvel*0.05;
yvel += ax*v[vi+1][vu].yvel*0.05;
xvel += ay*v[vi][vu+1].xvel*0.05;
yvel += ay*v[vi][vu+1].yvel*0.05;
v[vi][vu].yvel -= (1-ay)*0.003;
v[vi+1][vu].yvel -= ax*0.003;
if(v[vi][vu].yvel < 0) v[vi][vu].yvel *= 1.00025;
x += xvel;
y += yvel;
}
else {
reposition();
}
if(random(0,400) < 1) {
reposition();
}
xvel *= 0.6;
yvel *= 0.6;
}
}
class vbuffer
{
int x;
int y;
float xvel;
float yvel;
float pressurex = 0;
float pressurey = 0;
float pressure = 0;
vbuffer(int xIn,int yIn) {
x = xIn;
y = yIn;
pressurex = 0;
pressurey = 0;
}
void updatebuf(int i, int u) {
if(i>0 && i<lwidth && u>0 && u<lheight) {
pressurex = (v[i-1][u-1].xvel*0.5 + v[i-1][u].xvel + v[i-1][u+1].xvel*0.5 - v[i+1][u-1].xvel*0.5 - v[i+1][u].xvel - v[i+1][u+1].xvel*0.5);
pressurey = (v[i-1][u-1].yvel*0.5 + v[i][u-1].yvel + v[i+1][u-1].yvel*0.5 - v[i-1][u+1].yvel*0.5 - v[i][u+1].yvel - v[i+1][u+1].yvel*0.5);
pressure = (pressurex + pressurey)*0.25;
}
}
}
class vsquare {
int x;
int y;
float xvel;
float yvel;
float col;
vsquare(int xIn,int yIn) {
x = xIn;
y = yIn;
}
void addbuffer(int i, int u) {
if(i>0 && i<lwidth && u>0 && u<lheight) {
xvel += (vbuf[i-1][u-1].pressure*0.5
+vbuf[i-1][u].pressure
+vbuf[i-1][u+1].pressure*0.5
-vbuf[i+1][u-1].pressure*0.5
-vbuf[i+1][u].pressure
-vbuf[i+1][u+1].pressure*0.5
)*0.49;
yvel += (vbuf[i-1][u-1].pressure*0.5
+vbuf[i][u-1].pressure
+vbuf[i+1][u-1].pressure*0.5
-vbuf[i-1][u+1].pressure*0.5
-vbuf[i][u+1].pressure
-vbuf[i+1][u+1].pressure*0.5
)*0.49;
}
}
void updatevels(int mvelX, int mvelY) {
float adj;
float opp;
float dist;
float mod;
if(mousePressed) {
adj = x - mouseX;
opp = y - mouseY;
dist = sqrt(opp*opp + adj*adj);
if(dist < penSize) {
if(dist < 4) dist = penSize;
mod = penSize/dist;
xvel += mvelX*mod;
yvel += mvelY*mod;
}
}
if(randomGust > 0) {
adj = x - randomGustX;
opp = y - randomGustY;
dist = sqrt(opp*opp + adj*adj);
if(dist < randomGustSize) {
if(dist < res*2) dist = randomGustSize;
mod = randomGustSize/dist;
xvel += (randomGustMax-randomGust)*randomGustXvel*mod;
yvel += (randomGustMax-randomGust)*randomGustYvel*mod;
}
}
xvel *= 0.99;
yvel *= 0.98;
}
void addcolour(int amt) {
col += amt;
if(col > 196) col = 196;
}
void display(PGraphics g, int i, int u) {
float tcol = 0;
if(i>0 && i<lwidth-1 && u>0 && u<lheight-1) {
tcol = (+ v[i][u+1].col
+ v[i+1][u].col
+ v[i+1][u+1].col*0.5
)*0.3;
tcol = (int)(tcol+col*0.5);
}
g.fill(tcol);
g.rect(x,y,res,res);
col = 0;
}
}
/**/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment