// Constantes de posicion int ALTURA = 400; int ANCHURA = 400; // Constantes de tiempo int FRAMERATE = 30; long t = 0; // Variable de tiempo en ms int dt = 100/FRAMERATE; // Periodo de cambio de frame en ms int NUMVECINOS = 3; float HEXSIDE = 15; float PARTSZ = 2; float OFFSETX = 4; float OFFSETY = 4; float INERCIA = 0*0.9; float DAMPING = 5.75; int PERIODEUPDTOBJ = 4; // Periodo de actualización de objetivo de las particulas int PERIODEUPDTPTL = 30/FRAMERATE; // Periodo de actualización de dibujo de las particulas int FADING = 60; /* int NUMTRAZA = 2; */ float h = HEXSIDE * cos(PI/3); // height : altura del triangulito de la parte superior-inferior del hexagono float b = HEXSIDE * sin(PI/3); // base : base del triangulito de la parte superior-inferior del hexagono // Calcula constantes de la grilla float consta = 2 * HEXSIDE * sin(PI/3); float constb = 2 * HEXSIDE * (cos(PI/3) + 1); // Calcula maximos y minimos de la grilla int maxv = (int)ceil(4*(ALTURA)/constb); int maxu = (int)ceil((ANCHURA)/consta); int numP = 500; Particula[] particulas; color pcolor; // ------------------------------------------------------------------------------ Classes class Particula { int id; color c; float tamx = PARTSZ; float tamy = PARTSZ; /* float[][] traza = new float[NUMTRAZA][2]; */ int ui, vi, uf, vf, u, v; float xi, yi, xf, yf, x, y; float vel = 0; float dir; int accum; boolean motion = false; Particula(int uIn, int vIn, int id, color pcolor) { // Inicializar las posiciones de la particula u = ui = uf = uIn; v = vi = vf = vIn; calculateXiYi(); calculateXfYf(); x=xi; y=yi; accum = (int)random(100); // Inicializar la traza /* for(int i=0; i100)){ accum=accum%100; // Calcula los vecinos en la maya hexagonal int[][] vecinos = new int[NUMVECINOS][2]; int caso = v % 4; if(caso==0) { vecinos[0][0] = u; vecinos[0][1] = v - 1; vecinos[1][0] = u; vecinos[1][1] = v + 1; vecinos[2][0] = u - 1; vecinos[2][1] = v + 1; } else if (caso==1) { vecinos[0][0] = u; vecinos[0][1] = v - 1; vecinos[1][0] = u + 1; vecinos[1][1] = v - 1; vecinos[2][0] = u; vecinos[2][1] = v + 1; } else if (caso==2) { vecinos[0][0] = u; vecinos[0][1] = v - 1; vecinos[1][0] = u + 1; vecinos[1][1] = v + 1; vecinos[2][0] = u; vecinos[2][1] = v + 1; } else if (caso==3) { vecinos[0][0] = u - 1; vecinos[0][1] = v - 1; vecinos[1][0] = u; vecinos[1][1] = v + 1; vecinos[2][0] = u; vecinos[2][1] = v + 1; } // Elegir un vecino al azar int rand = int(random(3)); int uiold, viold; uiold = ui; viold = vi; uf = vecinos[rand][0]; vf = vecinos[rand][1]; ui = u; vi = v; if((uf>maxu)||(vf>maxv)||(uf<0)||(vf<0)){uf=u; ui=uiold; vf=v; vi=viold;} // Calcular nuevas posiciones y direccion calculateXiYi(); calculateXfYf(); calculateDir(); // Calcular nueva traza /* for(int i=NUMTRAZA-2; i>=0; i--) { traza[i+1][0] = traza[i][0]; traza[i+1][1] = traza[i][1]; } traza[0][0] = xi; traza[0][1] = yi; */ motion = true; //println("caso="+caso+"/rand="+rand+": ui="+ui+" vi="+vi+" -->> uf="+uf+" vf="+vf+";"+"xi="+xi+" yi="+yi+" -->> xf="+xf+" yf="+yf); }else if(!motion){ accum = accum + (int)random(60); } } void updatePos() { if(motion){ float dist = dist(xf,yf,x,y); if((dist < 0.5)) { x = xf; y = yf; vel = 0; u = uf; v = vf; motion = false; }else{ vel = dist/DAMPING; x = x + vel*cos(dir); y = y + vel*sin(dir); } } } void calculateXiYi() { int caso = vi % 4; if(caso==0) { xi = consta * ui + OFFSETX; yi = constb * floor(vi/4) + OFFSETY; } else if (caso==1) { xi = b + consta * ui + OFFSETX; yi = h + constb * floor(vi/4) + OFFSETY; } else if (caso==2) { xi = b + consta * ui + OFFSETX; yi = h + HEXSIDE + constb * floor(vi/4) + OFFSETY; } else if (caso==3) { xi = consta * ui + OFFSETX; yi = 2 * h + HEXSIDE + constb * floor(vi/4) + OFFSETY; } } void calculateXfYf() { int caso = vf % 4; if(caso==0) { xf = consta * uf + OFFSETX; yf = constb * floor(vf/4) + OFFSETY; } else if (caso==1) { xf = b + consta * uf + OFFSETX; yf = h + constb * floor(vf/4) + OFFSETY; } else if (caso==2) { xf = b + consta * uf + OFFSETX; yf = h + HEXSIDE + constb * floor(vf/4) + OFFSETY; } else if (caso==3) { xf = consta * uf + OFFSETX; yf = 2 * h + HEXSIDE + constb * floor(vf/4) + OFFSETY; } } void calculateDir() { dir = atan2(yf-y,xf-x); } } // ------------------------------------------------------------------------------ Controles boolean ctlFade = false; boolean ctlSmooth = false; void keyPressed() { if( key == 'o' ) {OFFSETY = OFFSETY+2*h;OFFSETX = OFFSETX+2*b;} if( key == 'f' ) ctlFade = !ctlFade; if( key == 's' ) ctlSmooth = !ctlSmooth; if( key == 'Z' ) saveFrame(); } // ------------------------------------------------------------------------------ Funciones Principales void setup() { framerate(FRAMERATE); size(ANCHURA, ALTURA); background(0); rectMode(CENTER_DIAMETER); noStroke(); //fill(255, 255, 255); // Color primario int kR = (int)random(255); int kG = (int)random(255); int kB = (int)random(255); println("R=" + kR + " G=" + kG + " B=" + kB); color pcolor = color(kR, kG, kB); // Creacion de las particulas particulas = new Particula[numP]; for(int i=0; i