Biyoon c; PImage[] imgs; void setup(){ size( 300, 300, P3D ); background( 255 ); c = new Biyoon( 100, 100, 100, 40, 19, 2 ); imgs = new PImage[2]; imgs[0] = loadImage( "nu.gif" ); imgs[1] = loadImage( "ru.gif" ); } void draw(){ background( 255 ); c.update_and_draw(); } void mousePressed(){ c.pressed(); } void mouseReleased(){ c.released(); } // Biyoon class Biyoon{ int xpos, ypos; int w, h; int wdiv, hdiv; int spring_num; Spring[] springs; int timer; int timer2; float nx, ny; float ndx, ndy; float alpha; Biyoon( int xpos, int ypos, int w, int h, int wdiv, int hdiv ){ this.xpos = xpos; this.ypos = ypos; this.w = w; this.h = h; this.wdiv = wdiv; this.hdiv = hdiv; spring_num = wdiv*hdiv; springs = new Spring[spring_num]; timer = 0; timer2 = 0; nx = random(width); ny = random(height); ndx = ndy = 0; alpha = 1; int x, y; int i, j, k, l; float dw, dh, dx, dy; float lenx, leny, len; dw = (float)w/(wdiv-1); dh = (float)h/(hdiv-1); for( y = 0; y < hdiv; y++ ){ for( x = 0; x < wdiv; x++ ){ i = x+y*wdiv; dx = dw*x+xpos; dy = dh*y+ypos; springs[i] = new Spring( dx, dy-x, 0.98, 60.0, 0.5 ); } } // link for( y = 0; y < hdiv-1; y++ ){ for( x = 0; x < wdiv-1; x++ ){ i = x+y*wdiv; j = (x+1)+y*wdiv; k = x+(y+1)*wdiv; l = (x+1)+(y+1)*wdiv; springs[i].add( springs[j], dw ); springs[j].add( springs[i], dw ); springs[i].add( springs[k], dh-x*2.5 ); springs[k].add( springs[i], dh-x*2.5 ); len = sqrt( dw*dw+dh*dh ); springs[i].add( springs[l], len ); springs[l].add( springs[i], len ); springs[j].add( springs[k], len ); springs[k].add( springs[j], len ); } } for( x = 0; x < wdiv-1; x++ ){ i = x+(hdiv-1)*wdiv; j = (x+1)+(hdiv-1)*wdiv; springs[i].add( springs[j], dw ); springs[j].add( springs[i], dw ); } for( y = 0; y < hdiv-1; y++ ){ i = (wdiv-1)+y*wdiv; j = (wdiv-1)+(y+1)*wdiv; springs[i].add( springs[j], dh ); springs[j].add( springs[i], dh ); } /*len = sqrt( w*w+h*h ); springs[0].add( springs[(wdiv-1)+(hdiv-1)*wdiv], len ); springs[(wdiv-1)+(hdiv-1)*wdiv].add( springs[0], len ); springs[(wdiv-1)].add( springs[(hdiv-1)*wdiv], len ); springs[(hdiv-1)*wdiv].add( springs[(wdiv-1)], len ); springs[0].add( springs[wdiv-1], w ); springs[wdiv-1].add( springs[0], w ); springs[(hdiv-1)*wdiv].add( springs[(wdiv-1)+(hdiv-1)*wdiv], w ); springs[(wdiv-1)+(hdiv-1)*wdiv].add( springs[(hdiv-1)*wdiv], w ); springs[0].add( springs[(hdiv-1)*wdiv], h ); springs[(hdiv-1)*wdiv].add( springs[0], h ); springs[wdiv-1].add( springs[(wdiv-1)+(hdiv-1)*wdiv], h ); springs[(wdiv-1)+(hdiv-1)*wdiv].add( springs[wdiv-1], h );*/ } void update_and_draw(){ int x, y, i; float lenx, leny, len; float crtx = springs[1*wdiv].xpos; float crty = springs[1*wdiv].ypos; lenx = nx-crtx; leny = ny-crty; len = sqrt( lenx*lenx+leny*leny ); nx += ndx; ny += ndy; if( len < 5 ){ ndx += lenx; ndy += leny; } ndx *= 0.98; ndy *= 0.98; if( nx < 0 ){ nx = 0; ndx *= -1; } else if( nx > width ){ nx = width; ndx *= -1; } if( ny < 0 ){ ny = 0; ndy *= -1; } else if( ny > height ){ ny = height; ndy *= -1; } float rad = atan2( ny-crty, nx-crtx )+PI/2; float vx1 = 0; float vy1 = -abs(cos((float)timer/100.0*PI*2)*0.1); float vx2 = vx1*cos(rad)-vy1*sin(rad); float vy2 = vx1*sin(rad)+vy1*cos(rad); float vx3 = 0; float vy3 = -abs(sin((float)timer/100.0*PI*2)*0.1); float vx4 = vx3*cos(rad)-vy3*sin(rad); float vy4 = vx3*sin(rad)+vy3*cos(rad); springs[0].velx += vx2*alpha; springs[0].vely += vy2*alpha; springs[wdiv].velx += vx2*alpha; springs[wdiv].vely += vy2*alpha; springs[(wdiv-1)].velx -= vx4*alpha*0.5; springs[(wdiv-1)].vely -= vy4*alpha*0.5; springs[(wdiv-1)+wdiv].velx -= vx4*alpha*0.5; springs[(wdiv-1)+wdiv].vely -= vy4*alpha*0.5; if( ++timer > 200 ){ timer = 0; alpha = random(random(10))+1; } for( y = 0; y < hdiv; y++ ){ for( x = 0; x < wdiv; x++ ){ i = x+y*wdiv; springs[i].update(); } } int j, k, l; float tw, th, tx, ty; PImage img; /*// draw line noFill(); stroke( 100 ); for( y = 0; y < hdiv-1; y++ ){ for( x = 0; x < wdiv-1; x++ ){ i = x+y*wdiv; j = (x+1)+y*wdiv; k = x+(y+1)*wdiv; l = (x+1)+(y+1)*wdiv; line( springs[i].xpos, springs[i].ypos, springs[j].xpos, springs[j].ypos ); line( springs[i].xpos, springs[i].ypos, springs[k].xpos, springs[k].ypos ); line( springs[i].xpos, springs[i].ypos, springs[l].xpos, springs[l].ypos ); line( springs[j].xpos, springs[j].ypos, springs[k].xpos, springs[k].ypos ); } } for( x = 0; x < wdiv-1; x++ ){ i = x+(hdiv-1)*wdiv; j = (x+1)+(hdiv-1)*wdiv; line( springs[i].xpos, springs[i].ypos, springs[j].xpos, springs[j].ypos ); } for( y = 0; y < hdiv-1; y++ ){ i = (wdiv-1)+y*wdiv; j = (wdiv-1)+(y+1)*wdiv; line( springs[i].xpos, springs[i].ypos, springs[j].xpos, springs[j].ypos ); }*/ // draw string fill( 255 ); noStroke(); for( x = 0; x < wdiv-1; x++ ){ img = imgs[x%2]; beginShape(TRIANGLE_STRIP); texture( img ); i = x; j = (x+1); k = x+wdiv; l = (x+1)+wdiv; vertex( springs[i].xpos, springs[i].ypos, 0, 0 ); vertex( springs[j].xpos, springs[j].ypos, img.width, 0 ); vertex( springs[k].xpos, springs[k].ypos, 0, img.height ); vertex( springs[l].xpos, springs[l].ypos, img.width, img.height ); endShape(); } /*// draw point noStroke(); fill( 40, 98, 146 ); for( i = 0; i < spring_num; i++ ){ ellipse( springs[i].xpos, springs[i].ypos, 2, 2 ); }*/ // draw target fill( 40, 98, 146 ); noStroke(); ellipse( nx, ny, 9, 9 ); noFill(); stroke( 40, 98, 146, 255-timer ); ellipse( nx, ny, timer/2, timer/2 ); } void pressed(){ int i; int hitidx; boolean hit; // hit test hitidx = -1; for( i = 0; i < spring_num; i++ ){ hit = false; hit = springs[i].hitTest( mouseX, mouseY ); if( hit ){ hitidx = i; break; } } if( !( hitidx < 0 ) ){ for( i = 0; i < spring_num; i++ ){ springs[i].released(); } springs[hitidx].pressed(); } } void released(){ int i; for( i = 0; i < spring_num; i++ ){ springs[i].released(); } } } // Spring class Spring{ float xpos, ypos; float txpos, typos; float size = 20; boolean press = false; float mass; float k = 0.2; float damp; float velx = 0; float vely = 0; float accel = 0; float force = 0; int maxfrd = 8; int nextfrd = 0; Spring[] friends; float[] lengths; Spring( float x, float y, float d, float m, float k_in ){ xpos = txpos = x; ypos = typos = y; damp = d; mass = m; k = k_in; int i; friends = new Spring[maxfrd]; lengths = new float[maxfrd]; } boolean add( Spring s, float len ){ if( nextfrd >= maxfrd ) return false; friends[nextfrd] = s; lengths[nextfrd] = len; nextfrd++; return true; } void update(){ int i; float lenx, leny, len, a; if( press ){ xpos = mouseX; ypos = mouseY; return; } for( i = 0; i < nextfrd; i++ ){ lenx = xpos - friends[i].xpos; leny = ypos - friends[i].ypos; len = sqrt( lenx*lenx+leny*leny ); a = (len-lengths[i])/len; force = -k*(ypos-friends[i].ypos); accel = force/mass; vely += accel*a; force = -k*(xpos-friends[i].xpos); accel = force/mass; velx += accel*a; } vely *= damp; velx *= damp; ypos += vely; xpos += velx; // rebound if( xpos < 0 ){ xpos = 0; velx *= -1; } else if( xpos > width ){ xpos = width; velx *= -1; } if( ypos < 0 ){ ypos = 0; vely *= -1; } else if( ypos > height ){ ypos = height; vely *= -1; } } void pressed(){ press = true; } void released(){ press = false; } boolean hitTest( int mx, int my ){ float xlen = (float)mx-xpos; float ylen = (float)my-ypos; float len = sqrt( xlen*xlen+ylen*ylen ); if( len < size ) return true; else return false; } }