/* built with Studio Sketchpad:
* https://sketchpad.cc
*
* observe the evolution of this sketch:
* https://studio.sketchpad.cc/sp/pad/view/ro.vb3yvpw2NUJ/rev.368
*
* authors:
* Farshid Naderi
* Sina Seifee
* license (unless otherwise specified):
* creative commons attribution-share alike 3.0 license.
* https://creativecommons.org/licenses/by-sa/3.0/
*/
// left click "Hate" ball.
// right click "Love" ball.
// middle click kill all balls.
// click and drag for move balls.
Ball[] balls = new Ball[0];
int grab = -1;
float time =0.0;
void setup() {
size(400,400);
smooth();
frameRate(25);
background(255);
for (int i=0; i<2; i++;){
makeNewBall("hate", random(width),random(height), random(5, 35));
makeNewBall("love", random(width),random(height), random(5, 35));
}
}
void draw() {
//background(20);
cursor(CROSS);
if(mousePressed == true){
selectBall();
if(grab>=0){
balls[grab].mouseMove();
}else{
if(mouseButton == LEFT)
makeNewBall("hate",mouseX, mouseY, random(5, 35) );
if(mouseButton == RIGHT)
makeNewBall("love",mouseX, mouseY, random(5, 35) );
if(mouseButton == CENTER)
balls = new Ball[0];
grab = balls.length-1;
}
}
for (int i = 0; i < balls.length; i = i+1) {
connectBall(i);
}
for (int i = 0; i < balls.length; i = i+1) {
if(i!=grab) balls[i].drag();
balls[i].display();
}
time+=1.01;
}
void mouseReleased() {
grab = -1;
}
void connectBall(int id) {
PVector push = new PVector(0,0);
PVector run = new PVector(0,0);
float dis = 0.0;
for (int i = 0; i < balls.length; i = i+1) {
if(i!=id && dist(balls[i].pos.x,balls[i].pos.y,balls[id].pos.x,balls[id].pos.y)< balls[id].rad*5 ){
stroke(balls[id].col);
if(random(5)<1)
nLine(balls[i].pos.x, balls[i].pos.y, balls[id].pos.x, balls[id].pos.y, id+i, 10);
if(random(10)<1)
nLine(balls[i].pos.x, balls[i].pos.y, balls[id].pos.x, balls[id].pos.y, id+i+5, 10);
if(random(15)<1)
nLine(balls[i].pos.x, balls[i].pos.y, balls[id].pos.x, balls[id].pos.y, id+i-5, 10);
dis = PVector.dist(balls[i].pos,balls[id].pos);
dis = norm(dis, balls[id].rad*5, 0);
if(balls[id].mode == "love")
run = PVector.sub(balls[i].pos,balls[id].pos);
if(balls[id].mode == "hate")
run = PVector.sub(balls[id].pos,balls[i].pos);
run.limit(2);
run.mult(dis);
}
if(i!=id && dist(balls[i].pos.x,balls[i].pos.y,balls[id].pos.x,balls[id].pos.y)< balls[i].rad*5 ){
dis = PVector.dist(balls[i].pos,balls[id].pos);
dis = norm(dis, balls[i].rad*5, 0);
if(balls[id].mode == "love")
push = PVector.sub(balls[i].pos,balls[id].pos);
if(balls[id].mode == "hate")
push = PVector.sub(balls[id].pos,balls[i].pos);
push.limit(4);
push.mult(dis);
}
}
run.add(push);
run.mult(balls[id].mass);
balls[id].influ = run;
}
void selectBall() {
if(grab==-1){
for (int i = 0; i < balls.length; i = i+1) {
if(dist(balls[i].pos.x,balls[i].pos.y,mouseX,mouseY) < balls[i].rad/2 ){
grab = balls[i].ID;
}
}
}
}
void makeNewBall(String mode, float x, float y, float rad) {
Ball newBall = new Ball(mode, balls.length , x, y, rad);
balls = (Ball[]) append(balls,newBall);
}
/////////////////////////////////////////
//---Noise Line
void nLine(float startX, float startY, float endX, float endY, float timeOffset, int pointCount){
noFill();
pointCount++;
float xDis = norm((startX-endX),0,width);
float yDis = norm((startY-endY),0,height)*-1;
float timeLine = time+timeOffset;
beginShape();
curveVertex(startX, startY); // control point (first)
curveVertex(startX, startY); // point of curve (first)
for (float i = 1.0; i < pointCount; i++) {
float step = i/pointCount;
float xMid = lerp(startX, endX,step);
float yMid = lerp(startY, endY,step);
float smoothing = (i<pointCount/2) ? step : (1-step);
float xNois= ( ( (noise(timeLine) )*2) -1)*yDis*smoothing*100;
float yNois= ( ( (noise(timeLine) )*2) -1)*xDis*smoothing*100;
curveVertex(xMid+xNois, yMid+yNois); //mid control point
//float rad = abs(sin(time))*5;
//ellipse(xMid+xNois, yMid+yNois, rad, rad);
timeLine += pointCount/pointCount;
}
curveVertex(endX, endY); // point of curve (last)
curveVertex(endX, endY); // control point (last)
endShape();
}
/////////////////////////////////////////
/////////////////////////////////////////
//// start class Ball ///////////////////
//
class Ball {
PVector pos;
PVector direct;
PVector influ;
String mode;
color col;
float speed;
float rad;
float mass;
int ID;
Ball(String ballBode, int ballID, float posx, float posy, float ballRad) {
ID = ballID;
mode = ballBode;
pos = new PVector(posx, posy);
direct= new PVector(0,0);
influ = new PVector(0.0,0.0);
rad = ballRad;
mass = map(rad, 35, 5, 1.1, 1.999);
if(mode == "love")
col = color(random(150,255), random(10,100), random(100,110));
if(mode == "hate")
col = color(random(20,50), random(50,255), random(50,255));
}
void display() {
stroke(255);
fill(col);
ellipse(pos.x,pos.y,rad,rad);
stroke(col,25);
fill(col,10);
//ellipse(pos.x,pos.y,rad*10,rad*10);
}
void mouseMove() {
pos.x = mouseX;
pos.y = mouseY;
direct.x = mouseX-pmouseX;
direct.y = mouseY-pmouseY;
}
void drag() {
direct.add(influ);
direct.mult(0.85);
pos.add(direct);
if (pos.x < 0){
direct.x *= -1;
pos.x = 1;
}
if(pos.x > width){
direct.x *= -1;
pos.x = width-1;
}
if (pos.y < 0){
direct.y *= -1;
pos.y = 1;
}
if(pos.y > height){
direct.y *= -1;
pos.y = height-1;
}
}
}
//
///////////////////// end class Ball ////
/////////////////////////////////////////