CellSet cellset; Raindrop[] raindrops; int rdn = 5; void setup(){ background( 0, 0, 0 ); size( 580, 380 ); cellset = new CellSet( 50, 50, 25, 15 ); raindrops = new Raindrop[rdn]; for( int i = 0; i < rdn; i++ ){ raindrops[i] = new Raindrop(); } } void draw(){ background( 0, 0, 100 ); /*for( int i = 0; i < rdn; i++ ){ raindrops[i].update(); raindrops[i].mappingTo( cellset ); }*/ cellset.update(); } //雨粒 class Raindrop{ float x, y; float dx, dy; Raindrop(){ init(); } private void init(){ x = random( width ); y = 0; dx = 10-random(20); dy = random(20)+20; } void mappingTo( CellSet cellset ){ int ix, iy; float lenx, leny, len; for( iy = 0; iy < cellset.h; iy++ ){ for( ix = 0; ix < cellset.w; ix++ ){ lenx = cellset.cells_a[ix+iy*cellset.w].x+cellset.x-x; leny = cellset.cells_a[ix+iy*cellset.w].y+cellset.y-y; len = sqrt( lenx*lenx+leny*leny ); if( len < Cell.CELL_W-7 ){ cellset.cells_a[ix+iy*cellset.w].dx2 += dx*0.4f; cellset.cells_a[ix+iy*cellset.w].dy2 += dy*0.4f; } if( ix < cellset.w-1 && iy < cellset.h-1 ){ lenx = cellset.cells_b[ix+iy*(cellset.w-1)].x+cellset.x-x; leny = cellset.cells_b[ix+iy*(cellset.w-1)].y+cellset.y-y; len = sqrt( lenx*lenx+leny*leny ); if( len < Cell.CELL_W-7 ){ cellset.cells_b[ix+iy*(cellset.w-1)].dx2 += dx*0.2f; cellset.cells_b[ix+iy*(cellset.w-1)].dy2 += dy*0.2f; } } } } } void update(){ //stroke( 255, 255, 255 ); //line( x, y, x+dx, y+dy ); x += dx; y += dy; if( x < 0 || x > width || y > height ){ init(); } } } //セルの管理クラス class CellSet{ int x, y; int w, h; Cell[] cells_a; Cell[] cells_b; private float windx, windy; private float windnx, windny; private float srcny, srcy; private int counter; CellSet( int x, int y, int w, int h ){ this.x = x; this.y = y; this.w = w; this.h = h; this.windx = this.windy = 0; this.windnx = this.windny = 0; this.srcny = this.srcy = 0; this.counter = 0; cells_a = new Cell[w*h]; cells_b = new Cell[(w-1)*(h-1)]; for( int iy = 0; iy < h; iy++ ){ for( int ix = 0; ix < w; ix++ ){ cells_a[ix+iy*w] = new Cell( ix*Cell.CELL_W, iy*Cell.CELL_H ); if( ix < w-1 && iy < h-1 ){ cells_b[ix+iy*(w-1)] = new Cell( ix*Cell.CELL_W+Cell.CELL_W/2, iy*Cell.CELL_H+Cell.CELL_H/2 ); } } } } void update(){ //風 if( counter++ > 20 ){ windnx = random(width)-width/2; windny = random(height)-height/2; srcny = random(h); counter = 0; } windx += (windnx-windx)*0.1f; windy += (windny-windy)*0.1f; srcy += (srcny-srcy)*0.1f; float da; for( int iy = 0; iy < h; iy++ ){ da = (1.0f-(float)abs(srcy-iy)/h)+0.3f; da *= da; cells_a[iy*w].move( windx*0.1f*da, windy*0.1f*da ); if( iy < h-1 ){ cells_b[iy*(w-1)].move( windx*0.02f*da, windy*0.02f*da ); } } //伝播 for( int iy = 0; iy < h; iy++ ){ for( int ix = w-1; ix >= 1; ix-- ){ cells_a[ix+iy*w].move( cells_a[(ix-1)+iy*w].dx, cells_a[(ix-1)+iy*w].dy ); if( ix < w-1 && iy < h-1 ){ cells_b[ix+iy*(w-1)].move( cells_b[(ix-1)+iy*(w-1)].dx, cells_b[(ix-1)+iy*(w-1)].dy ); } } } //描画 fill( 0, 0, 200 ); noStroke(); pushMatrix(); translate( x, y ); for( int iy = 0; iy < h; iy++ ){ for( int ix = 0; ix < w; ix++ ){ cells_a[ix+iy*w].update(); if( ix < w-1 && iy < h-1 ){ cells_b[ix+iy*(w-1)].update(); } } } popMatrix(); } } //セル(構成要素) class Cell{ float x, y; float tx, ty; float dx, dy; float dx2, dy2; static final float CELL_W = 20; static final float CELL_H = 20; Cell( float x, float y ){ this.x = this.tx = x; this.y = this.ty = y; this.dx = this.dy = 0; this.dx2 = this.dy2 = 0; } void move( float dx, float dy ){ this.dx = dx; this.dy = dy; x = tx + dx + dx2; y = ty + dy + dy2; dx2 *= 0.5f; dy2 *= 0.5f; } void update(){ ellipse( x, y, CELL_W-7, CELL_H-7 ); } }