/* __ _ __ _ _ __ ___ __ _ __ _| |_ ___ _ __ / _` |/ _` | '__/ _ \/ _` |/ _` | __/ _ \| '__| | (_| | (_| | | | __/ (_| | (_| | || (_) | | \__,_|\__, |_| \___|\__, |\__,_|\__\___/|_| |___/ |___/ */ #include #include #include #include #include #include "../libbubulle/bubulles.h" #include "funcs.h" /* --------------------------------------------------------------------- */ #define NB_PASSES 40000 #define COMBIEN (NB_PASSES*3) /* poudre verte */ #define NB_COLORS 357 #define INIT_TTL 1600 /* --------------------------------------------------------------------- */ static double distance_bouboule(Bubulle *a, Bubulle *b) { double d; d = sqrt( ((b->p.x - a->p.x) * (b->p.x - a->p.x)) + ((b->p.y - a->p.y) * (b->p.y - a->p.y)) + ((b->p.z - a->p.z) * (b->p.z - a->p.z)) ); return d; } /* --------------------------------------------------------------------- */ static int calcul_rgb_bouboules(BBList *bubl, int pass) { Bubulle *bptr, zero; int idx; double dist0, age, gray; double rouge, vert, bleu; double phyR, phyG; zero.p.x = zero.p.y = zero.p.z = 0.0; /* centre du monde */ phyR = 298.5*((double)pass/(double)(NB_PASSES)); phyG = 352.5*((double)pass/(double)(NB_PASSES)); bptr = bubl->bbs; /* array of bubbles */ for (idx=0; idxfidx; idx++) { dist0 = distance_bouboule(&bptr[idx], &zero); age = (double)(bptr[idx].ttl) / (double)INIT_TTL; gray = (double)(bptr[idx].gray) / (double)NB_COLORS; rouge = 0.502 + (sin((phyR+dist0)*9.205) / 2.05); vert = 0.502 + (sin(phyG+(dist0*4.414)) / 2.05); bleu = 0.502 + (sin(dist0*3.141) / 2.05); #if DEBUG_LEVEL > 1 if (42==idx) { fprintf(stderr, "%6d RGB %f %f %f %f\n", pass, age, gray, phyR, rouge); } #endif bptr[idx].col.r = (gray * age) + (rouge * (1.0 - age)); bptr[idx].col.g = (gray * age) + (vert * (1.0 - age)); bptr[idx].col.b = (gray * age) + (bleu * (1.0 - age)); if (bptr[idx].ttl > 0) bptr[idx].ttl --; } return -1; } /* --------------------------------------------------------------------- */ int bouboules_to_incc(BBList *bubl, int pass) { FILE *fp; int idx; double bx, by, bz; Bubulle *b; #if DEBUG_LEVEL > 1 fprintf(stderr, "-----> %s %p %d\n", __func__, bubl, pass); #endif b = bubulle_getaddr(bubl, 0); bx = by = bz = 0.0; /* calcul du barycentre */ calcul_rgb_bouboules(bubl, pass); if (NULL==(fp=fopen("bouboules.incc", "w"))) { perror(__func__); exit(1); } /* --- give more data to the raytracer --- */ fprintf(fp, "/* ---- file generated by pid %d */\n\n", getpid()); fprintf(fp, "// current pass : %d\n\n", pass); fprintf(fp, "#declare Number_of_frames = %d;\n", NB_PASSES); fprintf(fp, "\n#declare bouboules = object {\nunion {\n"); /* make the povray CSG parser happy with a dummy bubulle */ fprintf(fp, "sphere { <0, 0, 0> 0.0000001 }\n"); for (idx=0; idxfidx; idx++) { /* barycentre */ bx += b[idx].p.x; by += b[idx].p.y; bz += b[idx].p.z; #if DEBUG_LEVEL fprintf(fp, "// %d on %d\n", idx, bubl->fidx); fprintf(fp, "// ttl %ld ", b[idx].ttl); fprintf(fp, "// gray %d\n", b[idx].gray); #endif fprintf(fp, "sphere { <%f, %f, %f> %f \n", b[idx].p.x, b[idx].p.y, b[idx].p.z, b[idx].d); fprintf(fp, " texture { "); fprintf(fp, "pigment { color <%f, %f, %f> }\n", b[idx].col.r, b[idx].col.g, b[idx].col.b); fprintf(fp, " finish { phong 0.5 metallic 0.8 } }\n"); fputs(" }\n", fp); } fprintf(fp, " }\n}\n"); fprintf(fp, "// emplacement du barycentre\n"); fprintf(fp, "#declare BX = %f;\n", bx / (double)bubl->fidx); fprintf(fp, "#declare BY = %f;\n", by / (double)bubl->fidx); fprintf(fp, "#declare BZ = %f;\n", bz / (double)bubl->fidx); fclose(fp); return 0; } /* --------------------------------------------------------------------- */ static int faire_random_bouboule(Bubulle *ptrbb) { static int foo; int rnd; #if DEBUG_LEVEL > 2 fprintf(stderr, " %s %p\n", __func__, ptrbb); #endif ptrbb->p.x = drand48() * 35.0; ptrbb->p.y = 28.0; ptrbb->p.z = 28.0; rnd = rand(); if (rnd & 0x80) ptrbb->p.x *= -1.0; if (rnd & 0x40) ptrbb->p.y *= -1.0; if (rnd & 0x20) ptrbb->p.z *= -1.0; ptrbb->d = 0.05 + (0.11*drand48()); ptrbb->gray = ((foo++ % NB_COLORS) / 2) + (NB_COLORS / 4); ptrbb->ttl = INIT_TTL; return 0; } /* --------------------------------------------------------------------- */ static int deplace_bouboule(Bubulle *pbb, double dk) { pbb->p.x += (drand48()*dk) - (dk/2.0); pbb->p.y += (drand48()*dk) - (dk/2.0); pbb->p.z += (drand48()*dk) - (dk/2.0); if ( pbb->p.x < -20.5 ) pbb->p.x = -20.0; else if ( pbb->p.x > 20.5 ) pbb->p.x = 20.0; if ( pbb->p.y < -10.5 ) pbb->p.y = -10.0; else if ( pbb->p.y > 10.5 ) pbb->p.y = 10.0; if ( pbb->p.z < -10.5 ) pbb->p.z = -10.0; else if ( pbb->p.z > 10.5 ) pbb->p.z = 10.0; return 0; } /* --------------------------------------------------------------------- */ static int cherche_un_contact(Bubulle *bubs, int nbre, Bubulle *newbb) { int idx; double offset, ecart; for (idx=0; idxd + bubs[idx].d; ecart = distance_bouboule(newbb, &bubs[idx]); if (ecart < offset) { printf("contact %5d %12.6f %12.6f\n", idx, offset, ecart); return 1; } } return 0; } /* --------------------------------------------------------------------- */ /* * make taht, over an over, and over. */ int une_passe(BBList *bbl, int k) { Bubulle current; int iter; Bubulle *bubarray; faire_random_bouboule(¤t); #if DEBUG_LEVEL > 1 fprintf(stderr, "new bubulle at %11.6f %11.6f %11.6f\n", current.p.x, current.p.y, current.p.z); #endif if (NULL==(bubarray = bubulle_getaddr(bbl, 0))) { fprintf(stderr, "%s : something wrong with %p\n", __func__, bbl); exit(1); } for (iter=0; iter<2330000; iter++) { deplace_bouboule(¤t, 0.05); if (cherche_un_contact(bubarray, bbl->fidx, ¤t)) { push_bubulle(bbl, ¤t); fprintf(stderr, "cur slot %d\n", bbl->fidx); break; } } fprintf(stderr, "iter = %d\n", iter); return -1; } /* --------------------------------------------------------------------- */ #define PLOPFACTOR 2.718 static void init_bubulles(BBList *bbl, int flag) { Bubulle first; int foo; memset(&first, 0, sizeof(Bubulle)); for (foo=0; foo<100; foo++) { memset(&first, 0, sizeof(Bubulle)); first.p.x = (drand48() * 40.0) - 20.0; first.p.y = first.p.z = 0.0; first.d = 0.11; first.ttl = INIT_TTL*4; first.gray = rand() % NB_COLORS; push_bubulle(bbl, &first); niceprint_bubulle(&first, 0); } } /* --------------------------------------------------------------------- */ int grande_boucle(BBList *bbl, int nb_passes, int k) { int passe, foo; /* we have to put a seed bubulle */ init_bubulles(bbl, 0); for (passe=0; passe %d\n", foo); return -1; } if ( ! (passe%500) ) { bubulles_to_data("agregation.data", NULL, bbl, 1); } } return 0; } /* --------------------------------------------------------------------- */ int main(int argc, char *argv[]) { int foo; BBList *bublist; fprintf(stderr, "*** %s *** compiled %s %s\n", argv[0], __DATE__, __TIME__); bubulles_version(0); /* initialisation of da random world */ srand48(getpid()); srand(getpid()); bublist = alloc_bubulles("agregation fractale", COMBIEN, 0); foo = grande_boucle(bublist, NB_PASSES, 0); foo = bubulles_to_data("agregation.data", NULL, bublist, 1); printf("ecriture bubulles -> %d\n", foo); return 0; } /* --------------------------------------------------------------------- */