/* Compute the exact integration of the mipmap \a M within the ball of radius r and center (x0,y0,z0). The method is a simple scanning at the finest scale. */ Value computeExact( MipMap* M, int x0, int y0, int z0, Value r ) { Image* img = MipMap_get_image( M, M->max_lvl ); int minx = x0 - (int) ceil( r ); int miny = y0 - (int) ceil( r ); int minz = z0 - (int) ceil( r ); int maxx = x0 + (int) ceil( r ); int maxy = y0 + (int) ceil( r ); int maxz = z0 + (int) ceil( r ); minx = minx <= 0 ? 0 : minx; miny = miny <= 0 ? 0 : miny; minz = minz <= 0 ? 0 : minz; maxx = maxx >= img->size ? img->size-1 : maxx; maxy = maxy >= img->size ? img->size-1 : maxy; maxz = maxz >= img->size ? img->size-1 : maxz; Value r2 = r*r; Value acc = (Value) 0; for ( int z = minz; z <= maxz; ++z ) for ( int y = miny; y <= maxy; ++y ) for ( int x = minx; x <= maxx; ++x ) { if ( distance2( x0, y0, z0, x, y, z ) <= r2 ) { acc += Image_get( img, x, y, z ); nb_access_exact += 1; } nb_iteration_exact += 1; } return acc; }
void MipMap_init_from_image_and_functor( MipMap* mipmap, Image* img, VoxelFunctor f ) { assert( ( img->lvl >= 0 ) && ( img->lvl <= LVL ) ); mipmap->max_lvl = img->lvl; for ( int k = img->lvl; k >= 0; --k ) { Image_init( &mipmap->hierarchy[ k ], k ); } // Copy image with functor (a moment). Image* src = img; Image* dst = MipMap_get_image( mipmap, img->lvl ); for ( int z = 0; z < src->size; ++z ) for ( int y = 0; y < src->size; ++y ) for ( int x = 0; x < src->size; ++x ) Image_set( dst, x, y, z, f( Image_get( src, x, y, z ), x, y, z ) ); // Compute hierarchy for ( int k = img->lvl - 1; k >= 0; --k ) { Image* src = MipMap_get_image( mipmap, k+1 ); Image* dst = MipMap_get_image( mipmap, k ); for ( int z = 0; z < dst->size; ++z ) for ( int y = 0; y < dst->size; ++y ) for ( int x = 0; x < dst->size; ++x ) { Value f = Image_get( src, 2*x, 2*y, 2*z ); f += Image_get( src, 2*x+1, 2*y, 2*z ); f += Image_get( src, 2*x, 2*y+1, 2*z ); f += Image_get( src, 2*x+1, 2*y+1, 2*z ); f += Image_get( src, 2*x, 2*y, 2*z+1 ); f += Image_get( src, 2*x+1, 2*y, 2*z+1 ); f += Image_get( src, 2*x, 2*y+1, 2*z+1 ); f += Image_get( src, 2*x+1, 2*y+1, 2*z+1 ); Image_set( dst, x, y, z, f / (Value) 8 ); } } }
Distribution* Image_getDistribution(Image* img) { Distribution* r = Distribution_init(); double quadW = ((float)img->w)/FIELD_SIZE; double quadH = ((float)img->h)/FIELD_SIZE; double f = 1.0/(quadW*quadH); int i, j; for(i = 0; i < img->h; i++) { for(j = 0; j < img->w; j++) { r->data[Distribution_getIndex((int)(j/quadW), (int)(i/quadH))] += Image_get(img, j, i); } } for(i = 0; i < FIELD_SIZE; i++) { for(j = 0; j < FIELD_SIZE; j++) { r->data[Distribution_getIndex(j, i)] *= f; } } return r; }