Cell[] cells; float mx, my, nmx, nmy; int num; boolean visible; void setup(){ size( 600, 200 ); background( 0, 0, 0 ); int cwn = width/Cell.W; int chn = height/Cell.H; cells = new Cell[cwn*chn]; for( int y = 0; y < chn; y++ ){ for( int x = 0; x < cwn; x++ ){ cells[x+y*cwn] = new Cell( x*Cell.W, y*Cell.H ); } } mx = my = 0; num = 0; visible = true; } void draw(){ background( 0, 0, 0 ); int cwn = width/Cell.W; int chn = height/Cell.H; if( num++ > 20 ){ nmx = random(width); nmy = random(height); num = 0; } mx += (nmx-mx)*0.1; my += (nmy-my)*0.1; for( int y = 0; y < chn; y++ ){ cells[y*cwn].next( (int)(mx*0.1), (int)(my*0.1) ); } for( int y = 0; y < chn; y++ ){ for( int x = cwn-1; x >= 1; x-- ){ cells[x+y*cwn].next( cells[x-1+y*cwn].dx, cells[x-1+y*cwn].dy ); } } for( int y = 0; y < chn; y++ ){ for( int x = 0; x < cwn; x++ ){ noStroke(); fill( 255, 255, 255 ); cells[x+y*cwn].update(); } } if( !visible ) return; stroke( 255, 0, 0 ); strokeWeight( 3 ); noFill(); ellipseMode(CORNER); ellipse( mx-20, my-20, 40, 40 ); int xd = (int)mx-width/2; int yd = (int)my-height/2; int r = (int)sqrt( xd*xd+yd*yd )*2; ellipseMode(CENTER); ellipse( width/2, height/2, r, r ); line( width/2, height/2, mx, my ); } void mousePressed(){ visible = !visible; } class Cell{ int x, y, tx, ty, dx, dy; static final int W = 10; static final int H = 10; Cell( int x, int y ){ this.x = this.tx = x; this.y = this.ty = y; } void next( int dx, int dy ){ this.dx = dx; this.dy = dy; this.x = this.tx + dx; this.y = this.ty + dy; } void update(){ rect( this.x, this.y, Cell.W-5, Cell.H-5 ); } }