void SpaceGrid3D::insert_node(Node3D* n) { Vector3D pos = n->position(); GridIndex gi = grid_index(pos); if(cubes.find(gi) == cubes.end()) cubes[gi] = new GridCube(); cubes[gi]->push_back(n); }
/*! \brief * Adds an index into a grid cell. * * \param[in,out] d Grid information. * \param[in] cell Cell into which \p i should be added. * \param[in] i Index to add. */ static void grid_add_to_cell(gmx_ana_nbsearch_t *d, const ivec cell, int i) { int ci = grid_index(d, cell); if (d->ncatoms[ci] == d->catom_nalloc[ci]) { d->catom_nalloc[ci] += 10; srenew(d->catom[ci], d->catom_nalloc[ci]); } d->catom[ci][d->ncatoms[ci]++] = i; }
void grid_check(double R) { printf("Check GRID\n"); printf("Check GRID\n"); printf("Check GRID\n"); printf("GRID: %3.3f %3.3f\n", grid[0], grid[grid_n-1]); printf("grid_h1 : %3.3f %d\n", grid_h1, grid_n); int kk; kk = grid_index( R ); printf(" R = %1.3e\n", R); printf(" grid[kk-1] : %lf grid[kk] : %lf grid[kk+1] : %lf\n", grid[kk-1], grid[kk], grid[kk+1] ); exit(10); }
vector<Node3D*> SpaceGrid3D::find_neighbors(Node3D* n) { vector<Node3D*> res; int i, j, k; GridIndex gi, gj; Vector3D pos = n->position(); gi = grid_index(pos); // add nodes from own and neighboring cube for(i = gi.a - 1; i <= gi.a + 1; i++) for(j = gi.b - 1; j <= gi.b + 1; j++) for(k = gi.c - 1; k <= gi.c + 1; k++) { gj = GridIndex(i, j, k); if(cubes.find(gj) != cubes.end()) copy(cubes[gj]->begin(), cubes[gj]->end(), inserter(res, res.begin())); } return res; }
void * blobs2voxels_SimpleGrid( void * data ) { ThreadBlobsToVoxels * thread_data = (ThreadBlobsToVoxels *) data; const MultidimArray<double> *vol_blobs = thread_data->vol_blobs; const SimpleGrid *grid = thread_data->grid; const struct blobtype *blob = thread_data->blob; MultidimArray<double> *vol_voxels = thread_data->vol_voxels; const Matrix2D<double> *D = thread_data->D; int istep = thread_data->istep; MultidimArray<double> *vol_corr = thread_data->vol_corr; const MultidimArray<double> *vol_mask = thread_data->vol_mask; ; bool FORW = thread_data->FORW; int eq_mode = thread_data->eq_mode; int min_separation = thread_data->min_separation; int z_planes = (int)(ZZ(grid->highest) - ZZ(grid->lowest) + 1); Matrix2D<double> Dinv; // Inverse of D Matrix1D<double> act_coord(3); // Coord: Actual position inside // the voxel volume without deforming Matrix1D<double> real_position(3); // Coord: actual position after // applying the V transformation Matrix1D<double> beginZ(3); // Coord: Voxel coordinates of the // blob at the 3D point // (z0,YY(lowest),XX(lowest)) Matrix1D<double> beginY(3); // Coord: Voxel coordinates of the // blob at the 3D point // (z0,y0,XX(lowest)) Matrix1D<double> corner2(3), corner1(3); // Coord: Corners of the // blob in the voxel volume Matrix1D<double> gcurrent(3); // Position in g of current point MultidimArray<double> blob_table; // Something like a blobprint // but with the values of the // blob in space double d; // Distance between the center // of the blob and a voxel position int id; // index inside the blob value // table for tha blob value at // a distance d double intx, inty, intz; // Nearest integer voxel int i, j, k; // Index within the blob volume int process; // True if this blob has to be // processed double vol_correction=0; // Correction to apply to the // volume when "projecting" back SPEED_UP_temps012; // Some aliases #define x0 STARTINGX(*vol_voxels) #define xF FINISHINGX(*vol_voxels) #define y0 STARTINGY(*vol_voxels) #define yF FINISHINGY(*vol_voxels) #define z0 STARTINGZ(*vol_voxels) #define zF FINISHINGZ(*vol_voxels) #ifdef DEBUG bool condition = !FORW; if (condition) { (*vol_voxels)().printShape(); std::cout << std::endl; std::cout << "x0= " << x0 << " xF= " << xF << std::endl; std::cout << "y0= " << y0 << " yF= " << yF << std::endl; std::cout << "z0= " << z0 << " zF= " << zF << std::endl; std::cout << grid; } #endif // Invert deformation matrix ............................................ if (D != NULL) Dinv = D->inv(); // Compute a blob value table ........................................... blob_table.resize((int)(blob->radius*istep + 1)); for (size_t i = 0; i < blob_table.xdim; i++) { A1D_ELEM(blob_table, i) = kaiser_value((double)i/istep, blob->radius, blob->alpha, blob->order); #ifdef DEBUG_MORE if (condition) std::cout << "Blob (" << i << ") r=" << (double)i / istep << " val= " << A1D_ELEM(blob_table, i) << std::endl; #endif } int assigned_slice; do { assigned_slice = -1; do { pthread_mutex_lock(&blobs_conv_mutex); if( slices_processed == z_planes ) { pthread_mutex_unlock(&blobs_conv_mutex); return (void*)NULL; } for(int w = 0 ; w < z_planes ; w++ ) { if( slices_status[w]==0 ) { slices_status[w] = -1; assigned_slice = w; slices_processed++; for( int in = (w-min_separation+1) ; in <= (w+min_separation-1 ) ; in ++ ) { if( in != w ) { if( ( in >= 0 ) && ( in < z_planes )) { if( slices_status[in] != -1 ) slices_status[in]++; } } } break; } } pthread_mutex_unlock(&blobs_conv_mutex); } while( assigned_slice == -1); // Convert the whole grid ............................................... // Corner of the plane defined by Z. These coordinates are in the // universal coord. system Matrix1D<double> aux( grid->lowest ); k = (int)(assigned_slice + ZZ( grid->lowest )); ZZ(aux) = k; grid->grid2universe(aux, beginZ); Matrix1D<double> grid_index(3); // Corner of the row defined by Y beginY = beginZ; for (i = (int) YY(grid->lowest); i <= (int) YY(grid->highest); i++) { // First point in the row act_coord = beginY; for (j = (int) XX(grid->lowest); j <= (int) XX(grid->highest); j++) { VECTOR_R3(grid_index, j, i, k); #ifdef DEBUG if (condition) { printf("Dealing blob at (%d,%d,%d) = %f\n", j, i, k, A3D_ELEM(*vol_blobs, k, i, j)); std::cout << "Center of the blob " << act_coord.transpose() << std::endl; } #endif // Place act_coord in its right place if (D != NULL) { M3x3_BY_V3x1(real_position, *D, act_coord); #ifdef DEBUG if (condition) std::cout << "Center of the blob moved to " //ROB, the "moved" coordinates are in // real_position not in act_coord << act_coord.transpose() << std::endl; << real_position.transpose() << std::endl; #endif // ROB This is OK if blob.radius is in Cartesian space as I // think is the case } else real_position = act_coord; // These two corners are also real valued process = true; //ROB //This is OK if blob.radius is in Cartesian space as I think is the case V3_PLUS_CT(corner1, real_position, -blob->radius); V3_PLUS_CT(corner2, real_position, blob->radius); #ifdef DEFORM_BLOB_WHEN_IN_CRYSTAL //ROB //we do not need this, it is already in Cartesian space //if (D!=NULL) // box_enclosing(corner1,corner2, *D, corner1, corner2); #endif if (XX(corner1) >= xF) process = false; if (YY(corner1) >= yF) process = false; if (ZZ(corner1) >= zF) process = false; if (XX(corner2) <= x0) process = false; if (YY(corner2) <= y0) process = false; if (ZZ(corner2) <= z0) process = false; #ifdef DEBUG if (!process && condition) std::cout << " It is outside output volume\n"; #endif if (!grid->is_interesting(real_position)) { #ifdef DEBUG if (process && condition) std::cout << " It is not interesting\n"; #endif process = false; } #ifdef DEBUG if (condition) { std::cout << "Corner 1 for this point " << corner1.transpose() << std::endl; std::cout << "Corner 2 for this point " << corner2.transpose() << std::endl; } #endif if (process) { // Clip the corners to the volume borders XX(corner1) = ROUND(CLIP(XX(corner1), x0, xF)); YY(corner1) = ROUND(CLIP(YY(corner1), y0, yF)); ZZ(corner1) = ROUND(CLIP(ZZ(corner1), z0, zF)); XX(corner2) = ROUND(CLIP(XX(corner2), x0, xF)); YY(corner2) = ROUND(CLIP(YY(corner2), y0, yF)); ZZ(corner2) = ROUND(CLIP(ZZ(corner2), z0, zF)); #ifdef DEBUG if (condition) { std::cout << "Clipped and rounded Corner 1 " << corner1.transpose() << std::endl; std::cout << "Clipped and rounded Corner 2 " << corner2.transpose() << std::endl; } #endif if (!FORW) switch (eq_mode) { case VARTK: vol_correction = 0; break; case VMAXARTK: vol_correction = -1e38; break; } // Effectively convert long N_eq; N_eq = 0; for (intz = ZZ(corner1); intz <= ZZ(corner2); intz++) for (inty = YY(corner1); inty <= YY(corner2); inty++) for (intx = XX(corner1); intx <= XX(corner2); intx++) { int iz = (int)intz, iy = (int)inty, ix = (int)intx; if (vol_mask != NULL) if (!A3D_ELEM(*vol_mask, iz, iy, ix)) continue; // Compute distance to the center of the blob VECTOR_R3(gcurrent, intx, inty, intz); #ifdef DEFORM_BLOB_WHEN_IN_CRYSTAL // ROB //if (D!=NULL) // M3x3_BY_V3x1(gcurrent,Dinv,gcurrent); #endif V3_MINUS_V3(gcurrent, real_position, gcurrent); d = sqrt(XX(gcurrent) * XX(gcurrent) + YY(gcurrent) * YY(gcurrent) + ZZ(gcurrent) * ZZ(gcurrent)); if (d > blob->radius) continue; id = (int)(d * istep); #ifdef DEBUG_MORE if (condition) { std::cout << "At (" << intx << "," << inty << "," << intz << ") distance=" << d; std::cout.flush(); } #endif // Add at that position the corresponding blob value if (FORW) { A3D_ELEM(*vol_voxels, iz, iy, ix) += A3D_ELEM(*vol_blobs, k, i, j) * A1D_ELEM(blob_table, id); #ifdef DEBUG_MORE if (condition) { std::cout << " adding " << A3D_ELEM(*vol_blobs, k, i, j) << " * " << A1D_ELEM(blob_table, id) << " = " << A3D_ELEM(*vol_blobs, k, i, j)* A1D_ELEM(blob_table, id) << std::endl; std::cout.flush(); } #endif if (vol_corr != NULL) A3D_ELEM(*vol_corr, iz, iy, ix) += A1D_ELEM(blob_table, id) * A1D_ELEM(blob_table, id); } else { double contrib = A3D_ELEM(*vol_corr, iz, iy, ix) * A1D_ELEM(blob_table, id); switch (eq_mode) { case VARTK: vol_correction += contrib; N_eq++; break; case VMAXARTK: if (contrib > vol_correction) vol_correction = contrib; break; } #ifdef DEBUG_MORE if (condition) { std::cout << " adding " << A3D_ELEM(*vol_corr, iz, iy, ix) << " * " << A1D_ELEM(blob_table, id) << " = " << contrib << std::endl; std::cout.flush(); } #endif } } if (N_eq == 0) N_eq = 1; if (!FORW) { A3D_ELEM(*vol_blobs, k, i, j) += vol_correction / N_eq; #ifdef DEBUG_MORE std::cout << " correction= " << vol_correction << std::endl << " Number of eqs= " << N_eq << std::endl << " Blob after correction= " << A3D_ELEM(*vol_blobs, k, i, j) << std::endl; #endif } } // Prepare for next iteration XX(act_coord) = XX(act_coord) + grid->relative_size * (grid->basis)( 0, 0); YY(act_coord) = YY(act_coord) + grid->relative_size * (grid->basis)( 1, 0); ZZ(act_coord) = ZZ(act_coord) + grid->relative_size * (grid->basis)( 2, 0); }
int32_t main(int32_t argc, char *argv[]) { if( init_sdl2() ) { return 1; } SDL_Window* window; sdl2_window("test-grid", 100, 60, 1280, 720, &window); SDL_GLContext* context; sdl2_glcontext(3, 2, window, &context); if( init_vbo() ) { return 1; } printf("vbo\n"); struct Vbo vbo = {0}; vbo_create(&vbo); vbo_add_buffer(&vbo, SHADER_ATTRIBUTE_VERTEX, 3, GL_FLOAT, GL_STATIC_DRAW); vbo_add_buffer(&vbo, SHADER_ATTRIBUTE_VERTEX_NORMAL, 3, GL_FLOAT, GL_STATIC_DRAW); struct Ibo ibo = {0}; ibo_create(GL_TRIANGLES, GL_UNSIGNED_INT, GL_STATIC_DRAW, &ibo); struct Grid grid = {0}; grid_create(4,4,1,&grid); struct GridPages pages = {0}; grid_pages(&grid,2,2,1,&pages); grid_dump(grid,pages); struct GridIndex index = {0}; for( uint64_t z = 0; z < grid.size.z; z++ ) { for( uint64_t y = 0; y < grid.size.y; y++ ) { for( uint64_t x = 0; x < grid.size.x; x++ ) { grid_index_xyz(&grid, &pages, NULL, x, y, z, &index); printf("x:%lu y:%lu z:%lu page:%lu cell:%lu\n", x, y, z, index.page, index.cell); } } } printf("-----------\n"); struct GridBox box = {0}; box.position.x = 1; box.position.y = 1; box.position.z = 0; box.size.x = 2; box.size.y = 2; box.size.z = 1; box.level = 0; for( uint64_t z = 0; z < box.size.z; z++ ) { for( uint64_t y = 0; y < box.size.y; y++ ) { for( uint64_t x = 0; x < box.size.x; x++ ) { grid_index_xyz(&grid, &pages, &box, x, y, z, &index); printf("x:%lu y:%lu z:%lu page:%lu cell:%lu\n", x, y, z, index.page, index.cell); } } } struct GridSize size = {0}; uint64_t array_size = grid_levelsize(&grid, &pages, 0, &size)->array; for( int32_t i = 0; i < array_size; i++ ) { grid_index(&grid, &pages, NULL, i, &index); } uint64_t x = UINT64_MAX; printf("0x%lx\n", x); grid_alloc(&pages, 0, 0); grid_alloc(&pages, 1, 0); grid_alloc(&pages, 2, 0); grid_alloc(&pages, 3, 0); grid_set1(&grid, &pages, NULL, 23); grid_set1(&grid, &pages, &box, 42); printf("lala\n"); grid_pagebox(&grid, &pages, 3, 0, &box); printf("%lu %lu %lu %lu %lu %lu %d\n", box.position.x, box.position.y, box.position.z, box.size.x, box.size.y, box.size.z, box.level); /* grid_pageout(&grid, &pages, 0, NULL); */ /* printf("\n"); */ /* grid_pageout(&grid, &pages, 1, NULL); */ /* printf("\n"); */ /* grid_pageout(&grid, &pages, 2, NULL); */ /* printf("\n"); */ /* grid_pageout(&grid, &pages, 3, NULL); */ /* printf("\n"); */ return 0; }
/* Splines -> Voxels for a SimpleGrid -------------------------------------- */ void spatial_Bspline032voxels_SimpleGrid(const MultidimArray<double> &vol_splines, const SimpleGrid &grid, MultidimArray<double> *vol_voxels, const MultidimArray<double> *vol_mask = NULL) { Matrix1D<double> act_coord(3); // Coord: Actual position inside // the voxel volume without deforming Matrix1D<double> beginZ(3); // Coord: Voxel coordinates of the // blob at the 3D point // (z0,YY(lowest),XX(lowest)) Matrix1D<double> beginY(3); // Coord: Voxel coordinates of the // blob at the 3D point // (z0,y0,XX(lowest)) Matrix1D<double> corner2(3), corner1(3); // Coord: Corners of the // blob in the voxel volume Matrix1D<double> gcurrent(3); // Position in g of current point double intx, inty, intz; // Nearest integer voxel int i, j, k; // Index within the blob volume bool process; // True if this blob has to be // processed double spline_radius = 2 * sqrt(3.0); // Some aliases #define x0 STARTINGX(*vol_voxels) #define xF FINISHINGX(*vol_voxels) #define y0 STARTINGY(*vol_voxels) #define yF FINISHINGY(*vol_voxels) #define z0 STARTINGZ(*vol_voxels) #define zF FINISHINGZ(*vol_voxels) #ifdef DEBUG bool condition = true; (*vol_voxels)().printShape(); std::cout << std::endl; std::cout << "x0= " << x0 << " xF= " << xF << std::endl; std::cout << "y0= " << y0 << " yF= " << yF << std::endl; std::cout << "z0= " << z0 << " zF= " << zF << std::endl; std::cout << grid; #endif // Convert the whole grid ............................................... // Corner of the plane defined by Z. These coordinates are in the // universal coord. system grid.grid2universe(grid.lowest, beginZ); Matrix1D<double> grid_index(3); for (k = (int) ZZ(grid.lowest); k <= (int) ZZ(grid.highest); k++) { // Corner of the row defined by Y beginY = beginZ; for (i = (int) YY(grid.lowest); i <= (int) YY(grid.highest); i++) { // First point in the row act_coord = beginY; for (j = (int) XX(grid.lowest); j <= (int) XX(grid.highest); j++) { VECTOR_R3(grid_index, j, i, k); #ifdef DEBUG if (condition) { printf("Dealing spline at (%d,%d,%d) = %f\n", j, i, k, A3D_ELEM(vol_splines, k, i, j)); std::cout << "Center of the blob " << act_coord.transpose() << std::endl; } #endif // These two corners are also real valued process = true; if (XX(act_coord) >= xF) process = false; if (YY(act_coord) >= yF) process = false; if (ZZ(act_coord) >= zF) process = false; if (XX(act_coord) <= x0) process = false; if (YY(act_coord) <= y0) process = false; if (ZZ(act_coord) <= z0) process = false; #ifdef DEBUG if (!process && condition) std::cout << " It is outside output volume\n"; #endif if (!grid.is_interesting(act_coord)) { #ifdef DEBUG if (process && condition) std::cout << " It is not interesting\n"; #endif process = false; } if (process) { V3_PLUS_CT(corner1, act_coord, -spline_radius); V3_PLUS_CT(corner2, act_coord, spline_radius); #ifdef DEBUG if (condition) { std::cout << "Corner 1 for this point " << corner1.transpose() << std::endl; std::cout << "Corner 2 for this point " << corner2.transpose() << std::endl; } #endif // Clip the corners to the volume borders XX(corner1) = ROUND(CLIP(XX(corner1), x0, xF)); YY(corner1) = ROUND(CLIP(YY(corner1), y0, yF)); ZZ(corner1) = ROUND(CLIP(ZZ(corner1), z0, zF)); XX(corner2) = ROUND(CLIP(XX(corner2), x0, xF)); YY(corner2) = ROUND(CLIP(YY(corner2), y0, yF)); ZZ(corner2) = ROUND(CLIP(ZZ(corner2), z0, zF)); #ifdef DEBUG if (condition) { std::cout << "Clipped and rounded Corner 1 " << corner1.transpose() << std::endl; std::cout << "Clipped and rounded Corner 2 " << corner2.transpose() << std::endl; } #endif // Effectively convert for (intz = ZZ(corner1); intz <= ZZ(corner2); intz++) for (inty = YY(corner1); inty <= YY(corner2); inty++) for (intx = XX(corner1); intx <= XX(corner2); intx++) { int iz = (int)intz, iy = (int)inty, ix = (int)intx; if (vol_mask != NULL) if (!A3D_ELEM(*vol_mask, iz, iy, ix)) continue; // Compute the spline value at this point VECTOR_R3(gcurrent, intx, inty, intz); V3_MINUS_V3(gcurrent, act_coord, gcurrent); double spline_value = spatial_Bspline03(gcurrent); #ifdef DEBUG_MORE if (condition) { std::cout << "At (" << intx << "," << inty << "," << intz << ") value=" << spline_value; std::cout.flush(); } #endif // Add at that position the corresponding spline value A3D_ELEM(*vol_voxels, iz, iy, ix) += A3D_ELEM(vol_splines, k, i, j) * spline_value; #ifdef DEBUG_MORE if (condition) { std::cout << " adding " << A3D_ELEM(vol_splines, k, i, j) << " * " << value_spline << " = " << A3D_ELEM(vol_splines, k, i, j)* value_spline << std::endl; std::cout.flush(); } #endif } } // Prepare for next iteration XX(act_coord) = XX(act_coord) + grid.relative_size * grid.basis(0, 0); YY(act_coord) = YY(act_coord) + grid.relative_size * grid.basis(1, 0); ZZ(act_coord) = ZZ(act_coord) + grid.relative_size * grid.basis(2, 0); } XX(beginY) = XX(beginY) + grid.relative_size * grid.basis(0, 1); YY(beginY) = YY(beginY) + grid.relative_size * grid.basis(1, 1); ZZ(beginY) = ZZ(beginY) + grid.relative_size * grid.basis(2, 1); } XX(beginZ) = XX(beginZ) + grid.relative_size * grid.basis(0, 2); YY(beginZ) = YY(beginZ) + grid.relative_size * grid.basis(1, 2); ZZ(beginZ) = ZZ(beginZ) + grid.relative_size * grid.basis(2, 2); } }
/*! \brief * Does a grid search. */ static gmx_bool grid_search(gmx_ana_nbsearch_t *d, gmx_bool (*action)(gmx_ana_nbsearch_t *d, int i, real r2)) { int i; rvec dx; real r2; if (d->bGrid) { int nbi, ci, cai; nbi = d->prevnbi; cai = d->prevcai + 1; for (; nbi < d->ngridnb; ++nbi) { ivec cell; ivec_add(d->testcell, d->gnboffs[nbi], cell); /* TODO: Support for 2D and screw PBC */ cell[XX] = (cell[XX] + d->ncelldim[XX]) % d->ncelldim[XX]; cell[YY] = (cell[YY] + d->ncelldim[YY]) % d->ncelldim[YY]; cell[ZZ] = (cell[ZZ] + d->ncelldim[ZZ]) % d->ncelldim[ZZ]; ci = grid_index(d, cell); /* TODO: Calculate the required PBC shift outside the inner loop */ for (; cai < d->ncatoms[ci]; ++cai) { i = d->catom[ci][cai]; if (is_excluded(d, i)) { continue; } pbc_dx_aiuc(d->pbc, d->xtest, d->xref[i], dx); r2 = norm2(dx); if (r2 <= d->cutoff2) { if (action(d, i, r2)) { d->prevnbi = nbi; d->prevcai = cai; d->previ = i; return TRUE; } } } d->exclind = 0; cai = 0; } } else { i = d->previ + 1; for (; i < d->nref; ++i) { if (is_excluded(d, i)) { continue; } if (d->pbc) { pbc_dx(d->pbc, d->xtest, d->xref[i], dx); } else { rvec_sub(d->xtest, d->xref[i], dx); } r2 = norm2(dx); if (r2 <= d->cutoff2) { if (action(d, i, r2)) { d->previ = i; return TRUE; } } } } return FALSE; }
void count() { int i, j, k; int index; double rd; double e[3], eo[3], v[3]; double r1, r2, r3, r; double l, h2, l2; for(i=0; i<N; i++) { if( inside_sp(P[i][0], P[i][1], P[i][2]) != 0 ) continue; printf("\ri=%d\t%d%%", i, (int) 100 * i / N ); if( cyl_par.R_max[i] == -1 ) continue; if( cyl_ort.R_max[i] == -1 ) continue; r = P[i][2]; if( r == 0 ) { e[0] = 0; e[1] = 0; e[2] = 1; } else { e[0] = p[i][0] / r; e[1] = p[i][1] / r; e[2] = p[i][2] / r; } eo[0] = - e[1] / sqrt( e[1]*e[1] + e[0]*e[0]); eo[1] = e[0] / sqrt( e[1]*e[1] + e[0]*e[0]); eo[2] = 0; r1 = r - cyl_par.R_max[i]; r2 = r + cyl_par.R_max[i]; r3 = cyl_ort.R_max[i]; for(j=0; j<N; j++) { if( i == j ) continue; l = scalar_product(p[j], e); h2 = sqrt( P[j][2]*P[j][2] - l*l ); if( ( h2 < h ) & (l > r1)&(l < r2) ) { if( l > r ) l = l - r; else l = r - l; index = MAX(0, grid_index( l ) + 1 ); cyl_par.m[i][ index ] ++; } // oort v[0] = p[j][0] - p[i][0]; v[1] = p[j][1] - p[i][1]; v[2] = p[j][2] - p[i][2]; l = fabs( scalar_product( v, eo ) ); if( l < r3 ) { h2 = sqrt( v[0]*v[0] + v[1]*v[1] + v[2]*v[2] - l*l ); if( h2 < h ) { index = MAX(0, grid_index( l ) + 1 ); cyl_ort.m[i][ index ] ++; } } } } printf("\n"); }