// MBALL_01 // // metaballs reactive system // click/drag to interact // // Seb Chevrel | www.seb.cc // ——————————————————————————————————————————————————————————————— int WIDTH=400; int HEIGHT=400; int NUMNODES=6; float nodes[][]=new float[NUMNODES][6]; void setup() { size(WIDTH,HEIGHT); noBackground(); // init positions and radius for(int i=0;i<NUMNODES;i++) { nodes[i][0]=int(random(WIDTH)); nodes[i][1]=int(random(HEIGHT)); nodes[i][2]=random(250)+50; // radius nodes[i][3]=0; // not used nodes[i][4]=0; // vx nodes[i][5]=0; // vy } } void loop() { int sum; float dx=0; float dy=0; float fx=0; float fy=0; float d2=0; float d=0; // apply forces on system for(int n1=0; n1<NUMNODES;n1++) { for(int n2=n1; n2<NUMNODES; n2++) { if(n1==n2) continue; dx=nodes[n2][0]-nodes[n1][0]; dy=nodes[n2][1]-nodes[n1][1]; d2=dx*dx; d2+=dy*dy; d=sqrt(d2); if(d>10) { fx=dx/50 -dx*100/d2; // attraction/repulsion fy=dy/50 - dy*100/d2; nodes[n1][4]+=fx; nodes[n2][4]-=fx; nodes[n1][5]+=fy; nodes[n2][5]-=fy; } } // apply user force if mouse clicked if(mousePressed) { dx=mouseX-nodes[n1][0]; dy=mouseY-nodes[n1][1]; d2=dx*dx; d2+=dy*dy; if((d2<10000)&&(d2>10)) { fx=dx*100/d2 ; fy=dy*100/d2; nodes[n1][4]+=fx; nodes[n1][5]+=fy; } } } // update positions, apply friction for(int n=0; n<NUMNODES; n++) { nodes[n][0]+=nodes[n][4]; nodes[n][1]+=nodes[n][5]; nodes[n][4]*=0.95; nodes[n][5]*=0.95; } // render canvas for(int i=0;i<HEIGHT;i++) { for(int j=0;j<WIDTH;j++) { sum=0; for(int n=0; n<NUMNODES; n++) { dx=j-nodes[n][0]; dy=i-nodes[n][1]; dx=dx*dx; dy=dy*dy; d2=dx+dy; sum+=int(nodes[n][2]*5000/d2); } sum=int(sum/NUMNODES) ; if (sum>255) {sum=0;} sum=(sum<<8)+(sum<<16)+sum; pixels[i*WIDTH+j]=sum; } } }