/* built with Studio Sketchpad:
* https://sketchpad.cc
*
* observe the evolution of this sketch:
* https://studio.sketchpad.cc/sp/pad/view/ro.jYMoyy5DrCr/rev.10758
*
* authors:
* Benjamin Y
* license (unless otherwise specified):
* creative commons attribution-share alike 3.0 license.
* https://creativecommons.org/licenses/by-sa/3.0/
*/
/*
This sketch builds on a prior work, "Metaball", created by tester & Hyeongjik Song & [unnamed author]
http://studio.sketchpad.cc/sp/pad/view/ro.9t5U31ZG1MFHB/rev.109
*/
/** ELECTRONS 15 CC Simul-15n
* Cloned from Metaball, By Hyeongjik Song, #219
* By Benjamin Y, #18937
* There are text to help you learn about this sketch.
* There are also comments to help you.
*/
/* 20193-29418-29448-40292 */
alert('Instructions: \n Q key: BackgroundTeal mode \n W key: Disable/Enable Arrow Key Control \n E key: Show/Hide Rectangle');
//int numBlobs = int(random(88, 95)); // max 94
int numBlobs = int(prompt('Blobs? 87-95'));
if(numBlobs > 95) {
numBlobs = 95;
alert('Too Large! Set to 95');
} else if (numBlobs < 87) {
numBlobs = 87;
alert('Too Small! Set to 87');
}
// undefined problem solved
if (numBlobs == undefined) {
numBlobs = 91;
}
int[] blogPx = { 25, 90, 120, 140, 50, 50, 25, 60, 70, 50, 45, 25, 50, 40, 100, 50, 40, 60, 65, 75, /*20*/ 35, 70, 45, 55, 35, 45, 35, 35, 25, 125, /*30*/ 35, 25, 55, 25, 95, 85, 25, 30, 35, 125, /*40*/ 25, 35, 125, 120, 125, 55, 65, 25, 35, 105, /*50*/ 75, 25, 60, 30, 50, 20, 10, 20, 125, 105 /*60*/, 25, 15, 5, 5, 55, 25, 35, 125, 25, 95 /*70*/, 20, 20, 50, 60, 100, 25, 35, 65, 105, 105, /*80*/25, 65, 25, 75, 105, 25, 105, 65, 115, 25 /*90*/, 25, 5, 55, 65, 115, 105, 5 };
int[] blogPy = { 50, 120, 45, 120, 50, 30, 120, 60, 45, 70, 45, 120, 75, 35, 105, 45, 25, 95, 105, 115, /*20*/ 70, 55, 55, 125, 105, 105, 125, 115, 110, 95, /*30*/ 75, 90, 25, 125, 25, 125, 55, 35, 25, 15, 115, /*40*/ 65, 15, 85, 95, 125, 25, 125, 25, 65, 85, /*50*/ 95, 25, 100, 120, 25, 125, 115, 65, 75, 95/*60*/, 65, 75, 95, 5, 120, 10, 95, 90, 80, 120 /*70*/, 85, 95, 100, 100, 100, 105, 125, 115, 110, 120, /*80*/ 25, 25, 15, 65, 105, 105, 105, 105, 25, 20,/*90*/ 105, 25, 65, 75, 95, 45 };
// Velocity for each blob
float[] blogDx = { 1, 0.8, 0.6, -0.5, -0.1, -1, 1, 0.9, -0.4, -0.8, -0.3, 0.8, -0.3, -1, -0.4, -0.7, 0.5, 0.3, 0.7, 0.9, /*20*/ -0.1, 0.7, 0.4, 0.2, 0.9, -0.9, -1, -0.7, -0.2, 0.6, /*30*/ 0.2, -0.9, -0.1, 0.8, 0.1, 0.2, 0.1 , 0.9, 0.1, -0.7, 0.2, /*40*/ 0.1, -0.7, -1, -1, -0.5, 0.5, 0.2, 0.6, -0.1, 0.6, /*50*/ 0.6, 0.1, -0.3, -0.2, -0.2, -0.5, -0.1, 0.6, 0.9, 0.2 ,/*60*/ 0.9, -0.1, -0.9, 0.1, -0.8 , -0.2, -0.1, -0.1, -0.1, -0.9 /*70*/, 0.6, -0.3, -0.1, 1, -1 , 1, 0.5, 0.2, 0.7, 0.5 /*80*/, 0.1, -0.9, -0.3, -0.2, -0.1, -0.9, -0.9, -0.9, -0.7, -0.7, /*90*/, -0.9, 0.4, 0.2, 0.1, 0.4, 0.3, 0.7};
float[] blogDy = { 1, 1, -0.3, -0.9, 0.9, -0.4, -0.7, 0.1, 0.6, -0.8, -0.8, -0.7, 1, -0.5, 0.8, 0.9, 0.2, -0.4, 0.6, 0.8, /*20*/ -0.7, 0.2, 0.6, 0.9, 0.1, -0.1, 1, 0.4, 0.1, 0.8, /*30*/ 0.7, -0.1, 0.4, 0.2, 0.7, -0.3, -0.9, 0.1, 0.6, 0.3, -0.5, /*40*/ 0.1, -0.1, 0.4, 0.2, 0.1, -0.3, 0.8, 0.2, 0.3, 0.4, /*50*/ 0.1, 0.6, 0.3, 0.2, 0.2, 0.1, 0.6, 0.3, 0.7, 0.3 /*60*/, -0.9, -0.9, -0.8, -0.9, -0.3, 0.8, 0.2, 0.1, -0.6, 0.3 /*70*/, -0.9, 1, 1, -0.6, -0.1, -0.1, -0.8, -0.3, -0.1, -0.9 /*80*/, -0.2, -0.7, -0.4, -0.3, -0.2, -0.2, -0.2, -0.1, -0.2, -0.3 /*90*/, 0.2, -0.3, -0.2, 0.1, 0.5, 0.3};
text(blogDx.length, 30, 400);
text(blogDy.length, 30, 400);
PGraphics pg;
int[][] vy,vx;
String name = "Electrons 15 CC";//"Electrons "+String(blogPy.length)+" CC";
int vers = 15;
String author = "Benjamin Y, #18937";
String derv = "Metaball, by Hyeongjik Song, #219";
if (numBlobs > 90) {
int elSize = int(random(50, 200))*5;// smaller for fit
} else {
int elSize = int(random(100, 350))*5;// electron size
}
int textStep = random(16, 21);// text step
float bounceCost = random(0.40, 0.55);
float friction = 0.015;
float speedup = random(0.014, 0.01554); // speedup
int timerLoop = 0; // timer
int qd = 0;
int speed = 0;
boolean bgteal = false;
int rctX = 300;
int rctY = 300;
boolean rctC = true;
boolean rctS = true;
// background
/*point(random(600), random(600);
point(random(600), random(600);
point(random(600), random(600);
point(random(600), random(600);
point(random(600), random(600);*/
void setup() {
size(600, 600);
pg = createGraphics(200, 200);
vy = new int[numBlobs][pg.height];
vx = new int[numBlobs][pg.width];
strokeWeight(1);
}
void draw() {
/*for(x = 0, x > width, x+=20) {
line(x, 0, x, height);
}
for (y=0, y>height, y+=20) {
line(0, y, width, y);
}*/
timerLoop += 1;
// Change velocity by a bit
double devX = random(0, 1);
double devY = random(0, 1);
for(int i = 0; i < blogDx.length; i++) {
blogDx[i] += random(-devX, devX); // deviation
}
for(int i = 0; i < blogDy.length; i++) {
blogDy[i] += random(-devY, devY); // deviation
if(blogDy[i] < 0) {
blogDy[i] *= 0.99+random(-0.2, 0.2);
}
else {
blogDy[i] *= 0.99998+random(-0.2, 0.5);
}
}
for (int i=0; i<numBlobs; ++i) {
blogPx[i]+=blogDx[i];
blogPy[i]+=blogDy[i];
blogDx[i]+=random(friction-0.1, 0.03)-friction*2;
blogDy[i]+=random(friction-0.1, 0.03)-friction*2;
float blogDevMax = 0.6;
// bounce across screen
if (blogPx[i] < 20) {
blogDx[i] = -(blogDx[i]*bounceCost);
blogPx[i] = 25; // clump problem fix
blogDx[i] += random(-blogDevMax, blogDevMax);
}
if (blogPx[i] > pg.width-20) {
blogDx[i] = -(blogDx[i]*bounceCost);
blogPx[i] = pg.width-25;
blogDx[i] += random(-blogDevMax, blogDevMax);
}
if (blogPy[i] < 20) {
blogDy[i] = -(blogDy[i]*bounceCost);
blogPy[i] = 25;
blogDy[i] += random(-blogDevMax, blogDevMax);
}
if (blogPy[i] > pg.height-20) {
blogDy[i] = -(blogDy[i]*bounceCost);
blogPy[i] = pg.height-25;
blogDy[i] += random(-blogDevMax, blogDevMax);
}
for (int x = 0; x < pg.width; x++) {
vx[i][x] = int(sq(blogPx[i]-x));
}
for (int y = 0; y < pg.height; y++) {
vy[i][y] = int(sq(blogPy[i]-y));
}
}
// Output into a buffered image for reuse
pg.beginDraw();
pg.loadPixels();
for (int y = 0; y < pg.height; y++) {
for (int x = 0; x < pg.width; x++) {
int m = 1;
for (int i = 0; i < numBlobs; i++) {
// Increase this number to make your blobs bigger
m += elSize/(vy[i][y] + vx[i][x]+1);
}
pg.pixels[x+y*pg.width] = color(0, m+x, (x+m+y)/2);
}
}
pg.updatePixels();
pg.endDraw();
// Display the results
image(pg, 0, 0, width, height);
// Text average vel
double avX = 0;
double avY = 0;
for(int i = 0; i < blogDx.length; i++) {
avX += blogDx[i];
blogDx[i] *= speedup+ 1;
}
for(int i = 0; i < blogDy.length; i++) {
avY += blogDy[i];
blogDy[i] *= speedup + 1;
}
avX /= blogDx.length;
avY /= blogDy.length;
stroke(0, 128, 255);
noFill();
rect(50, 50, 600-100, 600-100);
stroke(0, 128, 255, 75);
rect(200, 200, 200, 200);
ellipse(300, 300, 600-100, 600-100);
line(50, 50, 600-50, 600-50);
line(600-50, 50, 50, 600-50);
line(50, 300, 600-50, 300);
line(300, 50, 300, 600-50);
line(175, 50, 600-175, 50);
line(175, 600-50, 600-175, 600-50);
line(50, 175, 50, 600-175);
line(600-50, 175, 600-50, 175);
fill(0, 128, 255);
ellipse(300, 300, 10, 10);
noFill();
ellipse(300, 300, 50, 50);
ellipse(300, 300, 100, 100);
ellipse(300, 300, 150, 150);
ellipse(300, 300, 200, 200);
ellipse(300, 300, 250, 250);
ellipse(300, 300, 300, 300);
ellipse(300, 300, 350, 350);
ellipse(300, 300, 400, 400);
ellipse(300, 300, 450, 450);
ellipse(300, 300, 500, 500);
ellipse(300, 300, 550, 550);
ellipse(300, 300, 600, 600);
ellipse(300, 300, 650, 650);
ellipse(300, 300, 700, 700);
ellipse(300, 300, 750, 750);
ellipse(300, 300, 800, 800);
stroke(0, 128, 255, 35);
ellipse(50, 50, 50, 50);
ellipse(50, 50, 100, 100);
ellipse(50, 550, 50, 50);
ellipse(50, 550, 100, 100);
ellipse(550, 50, 50, 50);
ellipse(550, 50, 100, 100);
ellipse(550, 550, 50, 50);
ellipse(550, 550, 100, 100);
stroke(0, 128, 255, 25);
ellipse(50, 300, 50, 50);
ellipse(50, 300, 100, 100);
ellipse(300, 50, 50, 50);
ellipse(300, 50, 100, 100);
ellipse(550, 300, 50, 50);
ellipse(550, 300, 100, 100);
ellipse(300, 550, 50, 50);
ellipse(300, 550, 100, 100);
ellipse(250, 300, 50, 50);
ellipse(300, 250, 50, 50);
ellipse(350, 300, 50, 50);
ellipse(300, 350, 50, 50);
ellipse(200, 200, 50, 50);
ellipse(400, 200, 50, 50);
ellipse(400, 400, 50, 50);
ellipse(200, 400, 50, 50);
ellipse(300, 300, 75, 400);
ellipse(300, 300, 75, 600);
ellipse(300, 300, 75, 200);
ellipse(300, 300, 400, 75);
ellipse(300, 300, 600, 75);
ellipse(300, 300, 200, 75);
ellipse(300, 300, 100, 200);
ellipse(300, 300, 200, 100);
fill(255, 102, 102);
text("0, 0", 300, 300);
text("-250, -250", 50, 50);
text("250, -250", 550, 50);
text("-250, 250", 50, 550);
text("250, 250", 550, 550);
text("0, -250", 300, 50);
text("-250, 0", 50, 300);
text("0, 250", 300, 550);
text("250, 0", 550, 300);
text("-100, 0", 200, 300);
text("0, -100", 300, 200);
text("100, 0", 400, 300);
text("0, 100", 300, 400);
text("-35, -35", 265, 265);
text("-35, 35", 265, 335);
text("35, -35", 335, 265);
text("35, 35", 335, 335);
text("-100, 0", 200, 300);
ellipse(200, 300, 5, 5);
ellipse(300, 200, 5, 5);
ellipse(400, 300, 5, 5);
ellipse(300, 400, 5, 5);
ellipse(265, 265, 5, 5);
ellipse(265, 335, 5, 5);
ellipse(335, 265, 5, 5);
ellipse(335, 335, 5, 5);
stroke(255, 102, 102, 204);
line(200, 300, 265, 265);
line(265, 265, 300, 200);
line(200, 300, 265, 335);
line(265, 335, 300, 400);
line(300, 400, 335, 335);
line(335, 335, 400, 300);
line(400, 300, 335, 265);
line(335, 265, 300, 200);
line(265, 265, 300, 300);
line(265, 335, 300, 300);
line(335, 265, 300, 300);
line(335, 335, 300, 300);
// SQRT 2 CALC
noFill();
sqrt2 = sqrt(2);
size1 = 35 * sqrt2 * 2;
ellipse(300, 300, size1, size1);
ellipse(300, 300, size1/2, size1/2);
strokeWeight(2);
arc(300, 300, size1, size1, 0+QUARTER_PI/2, HALF_PI-QUARTER_PI/2);
arc(300, 300, size1, size1, PI+QUARTER_PI/2, PI+HALF_PI-QUARTER_PI/2);
arc(300, 300, size1, size1, 0+QUARTER_PI/2+HALF_PI, HALF_PI-QUARTER_PI/2+HALF_PI);
arc(300, 300, size1, size1, PI+QUARTER_PI/2+HALF_PI, PI+HALF_PI-QUARTER_PI/2+HALF_PI);
arc(300, 300, 100, 100, 0+QUARTER_PI/2, HALF_PI-QUARTER_PI/2);
arc(300, 300, 100, 100, PI+QUARTER_PI/2, PI+HALF_PI-QUARTER_PI/2);
arc(300, 300, 100, 100, 0+QUARTER_PI/2+HALF_PI, HALF_PI-QUARTER_PI/2+HALF_PI);
arc(300, 300, 100, 100, PI+QUARTER_PI/2+HALF_PI, PI+HALF_PI-QUARTER_PI/2+HALF_PI);
strokeWeight(1);
size2 = 250 * sqrt2 * 2;
//console.log(size2);
ellipse(300, 300, size2, size2);
ellipse(300, 300, size2/2, size2/2);
stroke(255, 102, 102, 128);
ellipse(300, 300, size2/3, size2/3);
stroke(255, 102, 102, 64);
ellipse(300, 300, size2/4, size2/4);
stroke(255, 102, 102, 16);
//ellipse(300, 300, size2/5, size2/5);
ellipse(300, 300, size2/6, size2/6);
//ellipse(300, 300, size2/7, size2/7);
//ellipse(300, 300, size2/8, size2/8);
//ellipse(300, 300, size2/9, size2/9);
strokeWeight(5);
arc(300, 300, size2, size2, 0+QUARTER_PI/2, HALF_PI-QUARTER_PI/2);
arc(300, 300, size2, size2, PI+QUARTER_PI/2, PI+HALF_PI-QUARTER_PI/2);
arc(300, 300, size2, size2, 0+QUARTER_PI/2+HALF_PI, HALF_PI-QUARTER_PI/2+HALF_PI);
arc(300, 300, size2, size2, PI+QUARTER_PI/2+HALF_PI, PI+HALF_PI-QUARTER_PI/2+HALF_PI);
strokeWeight(1);
fill(255, 102, 102);
textSize(12);
//text('Average Dx:'+String(avX), 0, textStep);
text('Average Dy:'+String(avY), 0, 2*textStep);
//text('Average Vel:'+String((avX+avY)/2), 0, 3*textStep);
text('Mouse Pos:'+String(mouseX-300)+', '+String(mouseY-300), 0, 4*textStep);
text('PreMouse Pos:'+String(pmouseX-300)+', '+String(pmouseY-300), 0, 5*textStep);
text('# of Electrons:'+String(numBlobs), 0, 6*textStep);
text('Electron Size:'+String(elSize), 0, 7*textStep);
text('Version: 15 CC', 0, 8*textStep);
text('Bounce Cost:'+String(bounceCost*100)+'% ', 0, 9*textStep);
text('Friction Percentage:'+String(friction*100)+'% ', 0, 10*textStep);
text('Acceleration Percentage:'+String(speedup*100)+'% ', 0, 11*textStep);
text('Time:'+String(timerLoop)+'lps , ' +String(floor(timerLoop/25.0000000000199295835))+'lps25 , '+String(floor(timerLoop/60.0110293430291192264673625536355090000000009))+'lps60 , '+String(floor(timerLoop/2.932))+'lpi , '+String(floor(timerLoop/59.99918273849902909))+'lpix , '+String(floor(timerLoop/5.992142152599064))+'lpis , '+String(floor(timerLoop/59.9998839281948294829118492281944221827718928449281929190492844824988881999999999999909))+'lpisx', 0, 12*textStep);
text('Quad:#'+String(qd), 0, 13*textStep);
text('Computer Time', 0, 14*textStep);
text('Hours:'+String(hour()), 10, 15*textStep);
text('Minutes:'+String(minute()), 10, 16*textStep);
text('Seconds:'+String(second())/*+String(round(millis()/100))*/, 10, 17*textStep);
text('Mode: Simul-15n', 0, 18*textStep);
text('Author: Benjamin Y, #18937', 0, 19*textStep);
text('Cloned From: Metaball', 0, 20*textStep);
text('Author: by Hyeongjik Song, #219', 10, 21*textStep);
//text('Rect Pos:'+String(rectX-300)+', '+String(rectY-300), 0, 22*textStep);
//text('Deviation X:'+String(devX*10000)+'x10X4', 0, 12*textStep);
textSize(48);
text(name, 175, 80);
line(175, 80, 600-100, 80);
textSize(24);
text(author, 175, 125);
textSize(18);
text('Dervired from '+derv, 20, 575);
textSize(15);
text('Published with Creative Commons License, By Sketchpad', 20, 545);
textSize(12);
// TimerLine Tool
//StrokeWidth(12);
//line(0, 600, timerLoop, 600);
//StrokeWidth(1);
// Pointer Tool
ellipse(mouseX, mouseY, 10, 10);// center
ellipse(mouseX, mouseY, 5, 5);
line(mouseX+10, mouseY, mouseX-10, mouseY);// crosshair
line(mouseX, mouseY+10, mouseX, mouseY-10);
noStroke();
fill(255, 102, 102, 102);// outside
ellipse(mouseX, mouseY, 20, 20);
fill(255, 102, 102, 50);
ellipse(mouseX, mouseY, 50, 50);
fill(255, 102, 102, 30);
ellipse(mouseX, mouseY, 125, 125);
fill(255, 102, 102, 15);
ellipse(mouseX, mouseY, 300, 300);
fill(255, 102, 102, 7);
ellipse(mouseX, mouseY, 500, 500);
fill(255, 102, 102, 15);
noStroke();
if (((mouseX > 50) && (mouseX < 500)) && ((mouseX > 50) && (mouseX < 500))) {
line(mouseX+25, mouseY, mouseX-25, mouseY);
line(mouseX, mouseY+25, mouseX, mouseY-25);
}
// Quad tool
fill(255, 102, 102, 10);
qd = 0;
noStroke();
if ((mouseX < 300)&&(mouseY < 300)) {
rect(0, 0, 300, 300);
qd = 1;
}
else if ((mouseX > 300)&&(mouseY < 300)) {
rect(301, 0, 300, 300);
qd = 2;
}
else if ((mouseX < 300)&&(mouseY > 300)) {
rect(0, 301, 300, 300);
qd = 3;
}
else if ((mouseX > 300)&&(mouseY > 300)) {
rect(301, 301, 300, 300);
qd = 4;
}
else {
rect(0, 0, 600, 600);
}
fill(255, 102, 102, 5);
switch(qd) {
case 1:
rect(300, 300, 300, 300);
break;
case 2:
rect(0, 300, 300, 300);
break;
case 3:
rect(300, 0, 300, 300);
break;
case 4:
rect(0, 0, 300, 300);
}
// Vel tool
if(rctS) {
fill(0, 0, 0, 64);
rect(rctX-20, rctY-20, 40, 40);
fill(0, 0, 0, 32);
rect(rctX-40, rctY-40, 80, 80);
}
fill(0);
stroke(0);
text('Pointer', mouseX-4, mouseY+4);
text("20193-29418-29448-40292", 435, 585);
if (bgteal) {
background(0, 129, 128);
textSize(42);
text(String(mouseX-300)+', '+String(mouseY-300), 25, 400);
textSize(12);
}
}
void keyPressed() {
if( key == 'q' || key == 'Q') {
if (bgteal) {
bgteal = false;
} else {
bgteal = true;
}
} else if( key == 'w' || key == 'W') {
if (rctC) {
rctC = false;
} else {
rctC = true;
}
} else if( key == 'e' || key == 'E') {
if (rctS) {
rctS = false;
} else {
rctS = true;
}
} else if( key == CODED && keyCode == UP) {
if (rctC) {
rctY -= 10;
}
} else if( key == CODED && keyCode == DOWN) {
if (rctC) {
rctY += 10;
}
} else if( key == CODED && keyCode == LEFT) {
if (rctC) {
rctX -= 10;
}
} else if( key == CODED && keyCode == RIGHT) {
if (rctC) {
rctX += 10;
}
}
}