void lcs_length_serial(const grid_t* grid) { int i, j; for(i = 1; i <= grid->n; i++) { for(j = 1; j <= grid->m; j++) { cell_t* cell = grid_cell( grid, i, j ); //printf("(%i,%i)\n", i, j); if(grid->s1[i-1] == grid->s2[j-1]) { cell->len = grid_cell( grid, i-1, j-1 )->len + 1; cell->dir = upleft; } else { cell_t* cell_up = grid_cell( grid, i-1, j ); cell_t* cell_left = grid_cell( grid, i, j-1 ); if(cell_up->len >= cell_left->len) { cell->len = cell_up->len; cell->dir = up; } else { cell->len = cell_left->len; cell->dir = left; } } } } }
void UniformGrid::neighborhood_query(Vector3 _pt, double _radius, vector<GridPoint>* neighborhood) { double sqd_radius = _radius*_radius; Vector3 pt = _pt; Vector3 diag_sphere = Vector3(_radius,_radius,_radius); Vector3 ll_sphere = pt-diag_sphere, ur_sphere = pt+diag_sphere; int ll_x, ll_y, ll_z, ur_x, ur_y, ur_z; this->map_to_grid(ll_sphere, ll_x, ll_y, ll_z); this->map_to_grid(ur_sphere, ur_x, ur_y, ur_z); for(int z = ll_z; z <= ur_z; z++) { for(int y = ll_y; y <= ur_y; y++) { for(int x = ll_x; x <= ur_x; x++) { GridCell* next_cell = uniform_grid[z][y][x]; GridCellParams grid_cell(x, y, z, x_res, y_res, z_res, ll_bound, ur_bound); if(!next_cell->intersects_sphere(grid_cell, pt, _radius)) continue; for(int n = 0; n < next_cell->size(); n++) { GridPoint next_pt = next_cell->get_grid_point(n); if(next_pt.pt.sqdDist(pt) > sqd_radius) continue; neighborhood->push_back(next_pt); } } } } }
static void grid_object_update_data(Grid_Object *grid_object) { Element *elem = &grid_object->element; DiaObject *obj = &elem->object; ElementBBExtras *extra = &elem->extra_spacing; real inset = (grid_object->border_line_width - grid_object->gridline_width)/2.0; real cell_width = (elem->width - 2.0 * inset) / grid_object->grid_cols; real cell_height = (elem->height - 2.0 * inset) / grid_object->grid_rows; int i, j; coord left, top; extra->border_trans = grid_object->border_line_width / 2.0; element_update_boundingbox(elem); element_update_handles(elem); element_update_connections_rectangle(elem, grid_object->base_cps); obj->position = elem->corner; left = obj->position.x; top = obj->position.y; for (i = 0; i < grid_object->grid_cols; ++i) for (j = 0; j < grid_object->grid_rows; ++j) { int cell = grid_cell(i, j, grid_object->grid_rows, grid_object->grid_cols); grid_object->cells[cell].pos.x = left + inset + i*cell_width + cell_width/2.0; grid_object->cells[cell].pos.y = top + inset + j*cell_height + cell_height/2.0; } }
void lcs_backtrack_serial(const grid_t* grid, int i, int j, const int maxlen, char* res) { int pos = 0; while(i > 0 && j > 0) { cell_t* cell = grid_cell(grid, i, j); if( cell->dir == upleft ) { //printf(":%c @ %i/%i\n", grid->s1[i-1], i, j); res[pos++] = grid->s1[i-1]; i--; j--; } else if( cell->dir == up ) { i--; } else if( cell->dir == left) { j--; } else { printf("\n---WTF BAD CELL!--\n"); } } res[pos] = 0; strrev(res); }
void d8_upslope_cells( int x0, int y0, int x1, int y1, const array2d<T> &flowdirs,array2d<U> &upslope_cells ){ diagnostic("Setting up the upslope_cells matrix..."); upslope_cells.copyprops(flowdirs); upslope_cells.init(d8_NO_DATA); upslope_cells.no_data=d8_NO_DATA; diagnostic("succeeded.\n"); ProgressBar progress; std::queue<grid_cell> expansion; if(x0>x1){ std::swap(x0,x1); std::swap(y0,y1); } //Modified Bresenham Line-Drawing Algorithm int deltax=x1-x0; int deltay=y1-y0; float error=0; float deltaerr=(float)deltay/(float)deltax; if (deltaerr<0) deltaerr=-deltaerr; diagnostic_arg("Line slope is %f\n",deltaerr); int y=y0; for(int x=x0;x<=x1;x++){ expansion.push(grid_cell(x,y)); upslope_cells(x,y)=2; error+=deltaerr; if (error>=0.5) { expansion.push(grid_cell(x+1,y)); upslope_cells(x+1,y)=2; y+=sgn(deltay); error-=1; } } progress.start(flowdirs.data_cells); long int ccount=0; while(expansion.size()>0){ grid_cell c=expansion.front(); expansion.pop(); progress.update(ccount++); for(int n=1;n<=8;n++) if(!flowdirs.in_grid(c.x+dx[n],c.y+dy[n])) continue; else if(flowdirs(c.x+dx[n],c.y+dy[n])==NO_FLOW) continue; else if(flowdirs(c.x+dx[n],c.y+dy[n])==flowdirs.no_data) continue; else if(upslope_cells(c.x+dx[n],c.y+dy[n])==upslope_cells.no_data && n==inverse_flow[flowdirs(c.x+dx[n],c.y+dy[n])]){ expansion.push(grid_cell(c.x+dx[n],c.y+dy[n])); upslope_cells(c.x+dx[n],c.y+dy[n])=1; } } diagnostic_arg(SUCCEEDED_IN,progress.stop()); diagnostic_arg("Found %ld up-slope cells.\n",ccount); }
void d8_upslope_area(const array2d<T> &flowdirs, array2d<U> &area){ char_2d dependency; std::queue<grid_cell> sources; ProgressBar progress; diagnostic("\n###D8 Upslope Area\n"); diagnostic_arg( "The sources queue will require at most approximately %ldMB of RAM.\n", flowdirs.width()*flowdirs.height()*((long)sizeof(grid_cell))/1024/1024 ); diagnostic("Resizing dependency matrix..."); dependency.copyprops(flowdirs); diagnostic("succeeded.\n"); diagnostic("Setting up the area matrix..."); area.copyprops(flowdirs); area.init(0); area.no_data=d8_NO_DATA; diagnostic("succeeded.\n"); diagnostic("%%Calculating dependency matrix & setting no_data cells...\n"); progress.start( flowdirs.width()*flowdirs.height() ); #pragma omp parallel for for(int x=0;x<flowdirs.width();x++){ progress.update( x*flowdirs.height() ); for(int y=0;y<flowdirs.height();y++){ dependency(x,y)=0; if(flowdirs(x,y)==flowdirs.no_data){ area(x,y)=area.no_data; continue; } for(int n=1;n<=8;n++) if(!flowdirs.in_grid(x+dx[n],y+dy[n])) continue; else if(flowdirs(x+dx[n],y+dy[n])==NO_FLOW) continue; else if(flowdirs(x+dx[n],y+dy[n])==flowdirs.no_data) continue; else if(n==inverse_flow[(int)flowdirs(x+dx[n],y+dy[n])]) ++dependency(x,y); } } diagnostic_arg(SUCCEEDED_IN,progress.stop()); diagnostic("%%Locating source cells...\n"); progress.start( flowdirs.width()*flowdirs.height() ); for(int x=0;x<flowdirs.width();x++){ progress.update( x*flowdirs.height() ); for(int y=0;y<flowdirs.height();y++) if(flowdirs(x,y)==flowdirs.no_data) continue; else if(dependency(x,y)==0) sources.push(grid_cell(x,y)); } diagnostic_arg(SUCCEEDED_IN,progress.stop()); diagnostic("%%Calculating up-slope areas...\n"); progress.start(flowdirs.data_cells); long int ccount=0; while(sources.size()>0){ grid_cell c=sources.front(); sources.pop(); ccount++; progress.update(ccount); area(c.x,c.y)+=1; if(flowdirs(c.x,c.y)==NO_FLOW) continue; int nx=c.x+dx[(int)flowdirs(c.x,c.y)]; int ny=c.y+dy[(int)flowdirs(c.x,c.y)]; if(flowdirs.in_grid(nx,ny) && area(nx,ny)!=area.no_data){ area(nx,ny)+=area(c.x,c.y); if((--dependency(nx,ny))==0) sources.push(grid_cell(nx,ny)); } } diagnostic_arg(SUCCEEDED_IN,progress.stop()); }
void dinf_upslope_area_interval(const float_2d &flowdirs, grid_engine< boost::numeric::interval<T> > &area){ char_2d dependency; std::queue<grid_cell> sources; ProgressBar progress; diagnostic_arg("The sources queue will require at most approximately %ldMB of RAM.\n",flowdirs.width()*flowdirs.height()*((long)sizeof(grid_cell))/1024/1024); diagnostic("Setting up the dependency matrix..."); dependency.copyprops(flowdirs); dependency.init(0); diagnostic("succeeded.\n"); diagnostic("Setting up the area matrix..."); area.copyprops(flowdirs); area.init((float)0); area.no_data=dinf_NO_DATA; diagnostic("succeeded.\n"); bool has_cells_without_flow_directions=false; diagnostic("%%Calculating dependency matrix & setting no_data cells...\n"); progress.start( flowdirs.width()*flowdirs.height() ); #pragma omp parallel for reduction(|:has_cells_without_flow_directions) for(int x=0;x<flowdirs.width();x++){ progress.update( x*flowdirs.height() ); for(int y=0;y<flowdirs.height();y++){ if(flowdirs(x,y)==flowdirs.no_data){ area(x,y)=area.no_data; dependency(x,y)=9; //Note: This is an unnecessary safety precaution continue; } if(flowdirs(x,y)==NO_FLOW){ has_cells_without_flow_directions=true; continue; } int n_high,n_low; int nhx,nhy,nlx,nly; where_do_i_flow(flowdirs(x,y),n_high,n_low); nhx=x+dinf_dx[n_high],nhy=y+dinf_dy[n_high]; if(n_low!=-1){ nlx=x+dinf_dx[n_low]; nly=y+dinf_dy[n_low]; } if( n_low!=-1 && flowdirs.in_grid(nlx,nly) && flowdirs(nlx,nly)!=flowdirs.no_data ) dependency(nlx,nly)++; if( flowdirs.in_grid(nhx,nhy) && flowdirs(nhx,nhy)!=flowdirs.no_data ) dependency(nhx,nhy)++; } } diagnostic_arg(SUCCEEDED_IN,progress.stop()); if(has_cells_without_flow_directions) diagnostic("\033[91mNot all cells had defined flow directions! This implies that there will be digital dams!\033[39m\n"); diagnostic("%%Locating source cells...\n"); progress.start( flowdirs.width()*flowdirs.height() ); for(int x=0;x<flowdirs.width();x++){ progress.update( x*flowdirs.height() ); for(int y=0;y<flowdirs.height();y++) if(flowdirs(x,y)==flowdirs.no_data) continue; else if(flowdirs(x,y)==NO_FLOW) continue; else if(dependency(x,y)==0) sources.push(grid_cell(x,y)); } diagnostic_arg(SUCCEEDED_IN,progress.stop()); diagnostic("%%Calculating up-slope areas...\n"); progress.start( flowdirs.data_cells ); long int ccount=0; while(sources.size()>0){ grid_cell c=sources.front(); sources.pop(); ccount++; progress.update(ccount); if(flowdirs(c.x,c.y)==flowdirs.no_data) //TODO: This line shouldn't be necessary since NoData's do not get added below continue; area(c.x,c.y)+=1; if(flowdirs(c.x,c.y)==NO_FLOW) continue; int n_high,n_low,nhx,nhy,nlx,nly; where_do_i_flow(flowdirs(c.x,c.y),n_high,n_low); nhx=c.x+dinf_dx[n_high],nhy=c.y+dinf_dy[n_high]; float phigh,plow; area_proportion(flowdirs(c.x,c.y), n_high, n_low, phigh, plow); if(flowdirs.in_grid(nhx,nhy) && flowdirs(nhx,nhy)!=flowdirs.no_data) area(nhx,nhy)+=area(c.x,c.y)*(T)phigh; if(n_low!=-1){ nlx=c.x+dinf_dx[n_low]; nly=c.y+dinf_dy[n_low]; if(flowdirs.in_grid(nlx,nly) && flowdirs(nlx,nly)!=flowdirs.no_data){ area(nlx,nly)+=area(c.x,c.y)*(T)plow; if((--dependency(nlx,nly))==0) sources.push(grid_cell(nlx,nly)); } } if( flowdirs.in_grid(nhx,nhy) && flowdirs(nhx,nhy)!=flowdirs.no_data && (--dependency(nhx,nhy))==0) sources.push(grid_cell(nhx,nhy)); } diagnostic_arg(SUCCEEDED_IN,progress.stop()); }
/** Adjusts allocations for connection points; does not actually compute * them. This call should always be followed with a call to update_data. */ static void grid_object_reallocate_cells (Grid_Object* grid_object) { DiaObject* obj = &(grid_object->element.object); int old_rows = grid_object->cells_rows; int old_cols = grid_object->cells_cols; int new_rows = grid_object->grid_rows; int new_cols = grid_object->grid_cols; int i, j; ConnectionPoint* new_cells; if (old_rows == new_rows && old_cols == new_cols) return; /* no reallocation necessary */ /* If either new dimension is smaller, some connpoints will have to * be disconnected before reallocating */ /* implicit: if (new_rows < old_rows) */ for (j = new_rows; j < old_rows; ++j) for (i = 0; i < old_cols; ++i) { int cell = grid_cell(i, j, old_rows, old_cols); object_remove_connections_to(&grid_object->cells[cell]); } /* implicit: if (new_cols < old_cols) */ for (i = new_cols; i < old_cols; ++i) for (j = 0; j < old_rows && j < new_rows; ++j) /* don't double-delete */ { int cell = grid_cell(i, j, old_rows, old_cols); object_remove_connections_to(&grid_object->cells[cell]); } /* must be done after disconnecting */ /* obj->connections doesn't own the pointers, so just realloc; values * will be updated later */ obj->num_connections = GRID_OBJECT_BASE_CONNECTION_POINTS + new_rows*new_cols; obj->connections = (ConnectionPoint **) g_realloc(obj->connections, obj->num_connections * sizeof(ConnectionPoint *)); /* Can't use realloc; if grid has different dims, memory lays out * differently. Must copy by hand. */ new_cells = g_malloc(new_rows * new_cols * sizeof(ConnectionPoint)); for (i = 0; i < new_cols; ++i) for (j = 0; j < new_rows; ++j) { int oldloc = grid_cell(i,j,old_rows,old_cols); int newloc = grid_cell(i,j,new_rows,new_cols); connectionpoint_init(&new_cells[newloc], obj); obj->connections[GRID_OBJECT_BASE_CONNECTION_POINTS + newloc] = &new_cells[newloc]; if (i < old_cols && j < old_rows) { connectionpoint_update(&new_cells[newloc], &grid_object->cells[oldloc]); } } g_free(grid_object->cells); grid_object->cells = new_cells; grid_object->cells_rows = new_rows; grid_object->cells_cols = new_cols; }