void Garbrecht_GradientTowardsLower(const Array2D<T> &elevations, const Array2D<d8_flowdir_t> &flowdirs, garbrecht_flat_type &flats, Array2D<int32_t> &inc1){ int loops = 0; int number_incremented = -1; std::cerr<<"Setting up the inc1 matrix..."<<std::endl; inc1.resize(elevations); inc1.setAll(0); while(number_incremented!=0){ number_incremented=0; for(int i=0;i<(int)flats.size();i++){ bool increment_elevation=true; int x=flats[i].x; int y=flats[i].y; for(int n=1;n<=8;n++){ if( elevations(x+dx[n],y+dy[n])<elevations(x,y) && flowdirs(x+dx[n],y+dy[n])!=NO_FLOW && !flowdirs.isNoData(x+dx[n],y+dy[n]) ){ increment_elevation=false; break; } else if(inc1(x+dx[n],y+dy[n])<loops && elevations(x+dx[n],y+dy[n])==elevations(x,y) ){ increment_elevation=false; break; } } if(increment_elevation){ inc1(x,y)++; number_incremented++; } } loops++; } }
void TA_CTI( const Array2D<T> &flow_accumulation, const Array2D<U> &riserun_slope, Array2D<V> &result ){ Timer timer; RDLOG_ALG_NAME<<"d8_CTI"; if(flow_accumulation.width()!=riserun_slope.width() || flow_accumulation.height()!=riserun_slope.height()) throw std::runtime_error("Couldn't calculate CTI! The input matricies were of unequal dimensions!"); RDLOG_PROGRESS<<"Setting up the CTI matrix..."<<std::flush; result.resize(flow_accumulation); result.setNoData(-1); //Log(x) can't take this value of real inputs, so we're good RDLOG_PROGRESS<<"succeeded."; RDLOG_PROGRESS<<"Calculating CTI..."<<std::flush; timer.start(); #pragma omp parallel for collapse(2) for(int x=0;x<flow_accumulation.width();x++) for(int y=0;y<flow_accumulation.height();y++) if(flow_accumulation(x,y)==flow_accumulation.noData() || riserun_slope(x,y)==riserun_slope.noData()) result(x,y)=result.noData(); else result(x,y)=log( (flow_accumulation(x,y)/flow_accumulation.getCellArea()) / (riserun_slope(x,y)+0.001) ); RDLOG_TIME_USE<<"succeeded in "<<timer.stop()<<"s."; }
void d8_flow_directions( const Array2D<T> &elevations, Array2D<U> &flowdirs ){ ProgressBar progress; std::cerr<<"A D8 Flow Directions"<<std::endl; std::cerr<<"C TODO"<<std::endl; std::cerr<<"p Setting up the flow directions matrix..."<<std::endl; flowdirs.resize(elevations); flowdirs.setAll(NO_FLOW); flowdirs.setNoData(FLOWDIR_NO_DATA); std::cerr<<"p Calculating D8 flow directions..."<<std::endl; progress.start( elevations.width()*elevations.height() ); #pragma omp parallel for for(int y=0;y<elevations.height();y++){ progress.update( y*elevations.width() ); for(int x=0;x<elevations.width();x++) if(elevations(x,y)==elevations.noData()) flowdirs(x,y) = flowdirs.noData(); else flowdirs(x,y) = d8_FlowDir(elevations,x,y); } std::cerr<<"t Succeeded in = "<<progress.stop()<<" s"<<std::endl; }
void RobotWithGeometry::GetSelfCollisionPairs(Array2D<bool>& collision) const { collision.resize(geometry.size(),geometry.size(),false); for(int i=0;i<collision.m;i++) for(int j=0;j<collision.n;j++) if(selfCollisions(i,j) != NULL) collision(i,j) = true; }
int Application::main(int argc,char *argv[]) { // Process command line CommandLine cmd(argc,argv,""); if(cmd.numArgs()!=2) throw String("train-3state <alignment-file> <outfile>"); String infile=cmd.arg(0); String outfile=cmd.arg(1); // Initialization transCounts.resize(4,4); emitCounts.resize(4,nAlpha,nAlpha); transCounts.setAllTo(0); emitCounts.setAllTo(0); // Process all alignments (pairs of sequences in fasta file) FastaReader reader(infile,alphabet); String def1, seq1, def2, seq2; while(reader.nextSequence(def1,seq1) && reader.nextSequence(def2,seq2)) { Sequence S1(seq1,alphabet), S2(seq2,alphabet); updateCounts(S1,S2); } // Compute HMM parameters PairHMM hmm(alphabet,gapSymbol,4); hmm.setStateType(INSERTION_STATE,PHMM_INSERT); hmm.setStateType(DELETION_STATE,PHMM_DELETE); hmm.setStateType(MATCH_STATE,PHMM_MATCH); hmm.setStateType(0,PHMM_OTHER); for(STATE i=0 ; i<4 ; ++i) { double sum=0; for(STATE j=0 ; j<4 ; ++j) sum+=transCounts[i][j]; for(STATE j=0 ; j<4 ; ++j) hmm.setTransP(i,j,transCounts[i][j]/sum); } for(STATE k=0 ; k<4 ; ++k) { double sum=0; for(Symbol i=0 ; i<nAlpha ; ++i) for(Symbol j=0 ; j<nAlpha ; ++j) sum+=emitCounts(k,i,j); if(sum==0) sum=1; for(Symbol i=0 ; i<nAlpha ; ++i) for(Symbol j=0 ; j<nAlpha ; ++j) hmm.setEmitP(k,i,j,emitCounts(k,i,j)/sum); } // Save HMM hmm.save(outfile); return 0; }
ACO_Likelihooder(int numNodes,int numAlpha,Alphabet &alpha, MultSeqAlignment &A,int firstCol,int lastCol, RootNode *root,AlphabetMap &alphabetMap, MolecularSequenceType seqType) : A(A), numNodes(numNodes), numAlpha(numAlpha),alpha(alpha), firstCol(firstCol), lastCol(lastCol), alphabetMap(alphabetMap), seqType(seqType), gapSymbols(A.getGapSymbols()) { numCols=lastCol-firstCol+1; numNmers=pow((float)alphabetMap.getRangeSize(),(float)numCols); L.resize(numNodes,numNmers); }
DLLEXPORT void rasterize_bezigon(double * alpha_arr, const double * data, const int n, const int w, const int h) { //-- filter typedef FilterBox<1> FilterType; FilterType filter; //-- curves Array<Curve<2,2> > lines; Array<Curve<3,2> > quads; Array<Curve<4,2> > cubics; Array<Curve<3,3> > rquads; for (int i = 0; i < n; i += 6) { Curve<4,2> cubic; cubic.p[0].set(data[i], data[i+1]); cubic.p[1].set(data[i+2], data[i+3]); cubic.p[2].set(data[i+4], data[i+5]); cubic.p[3].set(data[(i+6)%n], data[(i+7)%n]); cubics.push_back(cubic); } //-- image Array2D<vect1d> img; int extra = (filter.W >> 1) << 1; img.resize(w + extra, h + extra); vect1d zero; zero = 0; img = zero; //-- color ColorFunction<1,1> color; color.comp[0].c[0] = 1; //-- rasterize RasterizerInstance<FilterType::W, 1, 1> inst( img, lines.s, quads.s, cubics.s, rquads.s); rasterize(inst, color, &lines, &filter.filter22[0], &quads, &filter.filter32[0], &cubics, &filter.filter42[0], &rquads, &filter.filter33[0]); //-- output for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { int idx = i*w + j; alpha_arr[idx] = img.data[idx].getitem(0); } } }
static inline void TerrainProcessor(F func, const Array2D<T> &elevations, const float zscale, Array2D<float> &output){ if(elevations.getCellLengthX()!=elevations.getCellLengthY()) RDLOG_WARN<<"Cell X and Y dimensions are not equal!"; output.resize(elevations); ProgressBar progress; progress.start(elevations.size()); #pragma omp parallel for for(int y=0;y<elevations.height();y++){ progress.update(y*elevations.width()); for(int x=0;x<elevations.width();x++) if(elevations.isNoData(x,y)) output(x,y) = output.noData(); else output(x,y) = func(elevations,x,y,zscale); } RDLOG_TIME_USE<<"Wall-time = "<<progress.stop(); }
void FindFlats( const Array2D<T> &elevations, Array2D<int8_t> &flats ){ flats.resize(elevations); flats.setNoData(FLAT_NO_DATA); ProgressBar progress; progress.start( elevations.size() ); #pragma omp parallel for for(int y=0;y<elevations.height();y++) for(int x=0;x<elevations.width();x++){ if(elevations.isNoData(x,y)){ flats(x,y) = FLAT_NO_DATA; continue; } if(elevations.isEdgeCell(x,y)){ flats(x,y) = NOT_A_FLAT; continue; } //We'll now assume that the cell is a flat unless proven otherwise flats(x,y) = IS_A_FLAT; for(int n=1;n<=8;n++){ const int nx = x+dx[n]; const int ny = y+dy[n]; if(elevations(nx,ny)<elevations(x,y) || elevations.isNoData(nx,ny)){ flats(x,y) = NOT_A_FLAT; break; } } //We handled the base case just above the for loop } RDLOG_TIME_USE<<"Succeeded in = "<<progress.stop()<<" s"; }
void Garbrecht_GradientAwayFromHigher(const Array2D<T> &elevations, const Array2D<d8_flowdir_t> &flowdirs, garbrecht_flat_type &flats, Array2D<int32_t> &inc2){ int loops = 0; int number_incremented = 0; std::cerr<<"Setting up the inc2 matrix..."<<std::endl; inc2.resize(elevations); inc2.setAll(0); while(number_incremented<(int)flats.size()){ for(int i=0;i<(int)flats.size();i++){ int x=flats[i].x; int y=flats[i].y; if(inc2(x,y)>0){ inc2(x,y)++; continue; } } for(int i=0;i<(int)flats.size();i++){ bool has_higher=false,has_lower=false; int x=flats[i].x; int y=flats[i].y; if(inc2(x,y)>0) continue; for(int n=1;n<=8;n++){ if( !has_higher && (elevations(x+dx[n],y+dy[n])>elevations(x,y) || inc2(x+dx[n],y+dy[n])==2) ) has_higher=true; else if( !has_lower && elevations(x+dx[n],y+dy[n])<elevations(x,y) ) has_lower=true; } if(has_higher && !has_lower){ inc2(x,y)++; number_incremented++; } } loops++; } }
// static bool PNGIO::write( const std::string& filename, Array2DReadView< uint8x4 > image ) { Array2D< uint8x4 > tmpImage; const uint8_t* srcPointer; if( !image.packed() ) { tmpImage.resize( image.size() ); copy< uint8x4 >( image, tmpImage ); srcPointer = reinterpret_cast< const uint8_t* >( tmpImage.pointer() ); } else { srcPointer = reinterpret_cast< const uint8_t* >( image.pointer() ); } unsigned int errVal = lodepng::encode( filename, srcPointer, image.width(), image.height(), LCT_RGBA ); bool succeeded = ( errVal == 0 ); return succeeded; }
void dinf_flow_directions(const Array2D<T> &elevations, Array2D<float> &flowdirs){ ProgressBar progress; std::cerr<<"\nA Dinf Flow Directions"<<std::endl; std::cerr<<"C Tarboton, D.G. 1997. A new method for the determination of flow directions and upslope areas in grid digital elevation models. Water Resources Research. Vol. 33. pp 309-319."<<std::endl; std::cerr<<"p Setting up the Dinf flow directions matrix..."<<std::endl; flowdirs.resize(elevations); flowdirs.setNoData(dinf_NO_DATA); flowdirs.setAll(NO_FLOW); std::cerr<<"p Calculating Dinf flow directions..."<<std::endl; progress.start( elevations.size() ); #pragma omp parallel for for(int y=0;y<elevations.height();y++){ progress.update( y*elevations.width() ); for(int x=0;x<elevations.width();x++) if(elevations(x,y)==elevations.noData()) flowdirs(x,y) = flowdirs.noData(); else flowdirs(x,y) = dinf_FlowDir(elevations,x,y); } std::cerr<<"t Succeeded in = "<<progress.stop()<<" s"<<std::endl; }
//******************** M A I N ************************ void get_font(string FontName_base, char letter, int ptsize, vect2d *times) { _mkdir("font_rasters"); std::string FontName = "fonts/" + FontName_base + ".ttf"; char buf[256]; string letter_name; letter_name += letter; if (letter >= 'A' && letter <= 'Z') letter_name += letter; //----------------------------------------- // Load contour of glyph //----------------------------------------- lines.clear(); bez2s.clear(); FT_Face face; FT_Library library; FT_Error error; error = FT_Init_FreeType( &library ); Check(error, "", "error initializing FT lib"); error = FT_New_Face( library, FontName.c_str(), 0, &face ); Check(error, "", "error loading font"); FT_F26Dot6 font_size = ptsize*64; error = FT_Set_Char_Size( face, font_size, font_size, 72, 72 ); Check(error, "", "error setting char size"); FT_UInt glyph_index = FT_Get_Char_Index( face, letter ); FT_Int32 load_flags = FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP; error = FT_Load_Glyph( face, glyph_index, load_flags ); Check(error, "", "error loading glyph"); FT_Glyph glyph; error = FT_Get_Glyph( face->glyph, &glyph ); Check(error, "", "error getting glyph"); FT_OutlineGlyph Outg; error = GetOutLine(glyph, &Outg); Check(error,"", "error getting outline"); // use my own callcacks to walk over the contour FT_Outline_Funcs func_interface; func_interface.shift = 0; func_interface.delta = 0; func_interface.move_to = move_to; func_interface.line_to = line_to; func_interface.conic_to = conic_to; func_interface.cubic_to = cubic_to; FT_Outline_Decompose(&Outg->outline, &func_interface, 0); //----------------------------------------- // Rasterize using FreeType //----------------------------------------- // rasterize using FreeType so that a comparison to my code can be made double t_ft_start = get_time(); FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); double t_ft_stop = get_time(); // save timing FILE *fa = fopen("timings.txt", "a"); fprintf(fa, "time FreeType = %f\n", t_ft_stop - t_ft_start); fclose(fa); // create grid / calculate resolution g.max_depth = 0; g.grid_res = 2; int maxsize = max(face->glyph->bitmap.width, face->glyph->bitmap.rows); while (g.grid_res < maxsize) { g.grid_res *= 2; g.max_depth++; } vect2i offset; offset.set((g.grid_res - face->glyph->bitmap.width) / 2, (g.grid_res - face->glyph->bitmap.rows) / 2); // copy bitmap into a buffer Array2D<vect3ub> ftgrid; ftgrid.resize(g.grid_res, g.grid_res); for (int k = 0; k < g.grid_res*g.grid_res; k++) ftgrid.data[k].set(0); for (int j = 0; j < face->glyph->bitmap.rows; j++) { unsigned char *row = face->glyph->bitmap.buffer + (face->glyph->bitmap.rows-j-1)*face->glyph->bitmap.pitch; for (int i = 0; i < face->glyph->bitmap.width; i++) { ftgrid(i + offset[0], j + offset[1]) = row[i]; } } sprintf(buf, "font_rasters/%s_%04d_%s_1_ft.png", FontName_base.c_str(), ptsize, letter_name.c_str()); save_png(buf, ftgrid); //----------------------------------------- // Rasterize using our method //----------------------------------------- // get bbox FT_BBox bbox; FT_Outline_Get_BBox(&Outg->outline, &bbox); //printf("bbox = (%f, %f), (%f, %f)\n", bbox.xMin/64., bbox.yMin/64., bbox.xMax/64., bbox.yMax/64.); // fit in box vect2f ext; ext.set(bbox.xMax/64. - bbox.xMin/64., bbox.yMax/64. - bbox.yMin/64.); float maxext = std::max(ext[0], ext[1]) * 1.1; for (int i = 0; i < lines.s; i++) { //printf("line\n"); for (int j = 0; j < 2; j++) { lines[i][j][0] = (lines[i][j][0] - floor(bbox.xMin/64.) + offset[0]) / g.grid_res; lines[i][j][1] = (lines[i][j][1] - floor(bbox.yMin/64.) + offset[1]) / g.grid_res; //printf("%f %f\n", lines[i][j][0], lines[i][j][1]); } } for (int i = 0; i < bez2s.s; i++) { //printf("bez2\n"); for (int j = 0; j < 3; j++) { bez2s[i][j][0] = (bez2s[i][j][0] - floor(bbox.xMin/64.) + offset[0]) / g.grid_res; bez2s[i][j][1] = (bez2s[i][j][1] - floor(bbox.yMin/64.) + offset[1]) / g.grid_res; //printf("%f %f\n", bez2s[i][j][0], bez2s[i][j][1]); } } //vect3ub *grid = new vect3ub [g.grid_res*g.grid_res]; Array2D<float> grid; Array2D<vect3ub> ourgrid; grid.resize(g.grid_res, g.grid_res); ourgrid.resize(g.grid_res, g.grid_res); // rasterize for (int k = 0; k < g.grid_res*g.grid_res; k++) grid.data[k] = 0; double t_ours_start = get_time(); raster_poly(lines, bez2s, grid.data); double t_ours_stop = get_time(); // save timing FILE *f = fopen("timings.txt", "a"); fprintf(f, "time wavelet = %f\n", (t_ours_stop - t_ours_start)); fclose(f); // copy into color image and save for (int k = 0; k < g.grid_res*g.grid_res; k++) { if (grid.data[k] >= 1) ourgrid.data[k] = 255; else if (grid.data[k] <= 0) ourgrid.data[k] = 0; else ourgrid.data[k] = grid.data[k]*255; } sprintf(buf, "font_rasters/%s_%04d_%s_2_ours.png", FontName_base.c_str(), ptsize, letter_name.c_str()); save_png(buf, ourgrid); //----------------------------------------- // Calculate difference between renders //----------------------------------------- Array2D<vect3ub> grid_dif; grid_dif.resize(g.grid_res, g.grid_res); for (int i = 0; i < grid_dif.data_size; i++) { int dif = (grid.data[i]*255 - ftgrid.data[i][0]) * 10; if (dif > 255) dif = 255; else if (dif < -255) dif = -255; #if 1 grid_dif.data[i] = 255; if (dif < 0) { grid_dif.data[i][0] += dif; grid_dif.data[i][1] += dif; } else { grid_dif.data[i][1] -= dif; grid_dif.data[i][2] -= dif; } #else grid_dif.data[i] = 0; if (dif < 0) grid_dif.data[i][2] -= dif; else grid_dif.data[i][0] += dif; #endif } sprintf(buf, "font_rasters/%s_%04d_%s_3_dif.png", FontName_base.c_str(), ptsize, letter_name.c_str()); save_png(buf, grid_dif); //printf("--== timing comparison ==--\n"); //printf("time freetype = %f\n", t_ft_stop - t_ft_start); //printf("time wavelets = %f\n", t_ours_stop - t_ours_start); //printf("times slower = %f\n", (t_ours_stop - t_ours_start) / (t_ft_stop - t_ft_start) ); if (times) { times->v[0] += t_ft_stop - t_ft_start; times->v[1] += t_ours_stop - t_ours_start; } }
void pit_mask(const Array2D<elev_t> &elevations, Array2D<int32_t> &pit_mask) { grid_cellz_pq<elev_t> open; std::queue<grid_cellz<elev_t> > pit; unsigned long processed_cells = 0; unsigned long pitc = 0; ProgressBar progress; std::cerr << "\n###Pit Mask" << std::endl; std::cerr << "Setting up boolean flood array matrix..." << std::flush; Array2D<int8_t> closed(elevations.viewWidth(), elevations.viewHeight(), false); std::cerr << "succeeded." << std::endl; std::cerr << "Setting up the pit mask matrix..." << std::endl; pit_mask.resize(elevations.viewWidth(), elevations.viewHeight()); pit_mask.setNoData(3); std::cerr << "succeeded." << std::endl; std::cerr << "The priority queue will require approximately " << (elevations.viewWidth() * 2 + elevations.viewHeight() * 2)*((long)sizeof(grid_cellz<elev_t>)) / 1024 / 1024 << "MB of RAM." << std::endl; std::cerr << "Adding cells to the priority queue..." << std::flush; for (int x = 0; x < elevations.viewWidth(); x++) { open.push_cell(x, 0, elevations(x, 0)); open.push_cell(x, elevations.viewHeight() - 1, elevations(x, elevations.viewHeight() - 1)); closed(x, 0) = true; closed(x, elevations.viewHeight() - 1) = true; } for (int y = 1; y < elevations.viewHeight() - 1; y++) { open.push_cell(0, y, elevations(0, y)); open.push_cell(elevations.viewWidth() - 1, y, elevations(elevations.viewWidth() - 1, y)); closed(0, y) = true; closed(elevations.viewWidth() - 1, y) = true; } std::cerr << "succeeded." << std::endl; std::cerr << "%%Performing the pit mask..." << std::endl; progress.start(elevations.viewWidth()*elevations.viewHeight()); while (open.size() > 0 || pit.size()>0) { grid_cellz<elev_t> c; if (pit.size() > 0) { c = pit.front(); pit.pop(); } else { c = open.top(); open.pop(); } processed_cells++; for (int n = 1; n <= 8; n++) { int nx = c.x + dx[n]; int ny = c.y + dy[n]; if (!elevations.in_grid(nx, ny)) continue; if (closed(nx, ny)) continue; closed(nx, ny) = true; if (elevations(nx, ny) <= c.z) { if (elevations(nx, ny) < c.z) pit_mask(nx, ny) = 1; pit.push(grid_cellz<elev_t>(nx, ny, c.z)); } else { pit_mask(nx, ny) = 0; open.push_cell(nx, ny, elevations(nx, ny)); } } if (elevations(c.x, c.y) == elevations.noData()) pit_mask(c.x, c.y) = pit_mask.noData(); progress.update(processed_cells); } std::cerr << "\t\033[96msucceeded in " << progress.stop() << "s.\033[39m" << std::endl; std::cerr << processed_cells << " cells processed. " << pitc << " in pits." << std::endl; }
void priority_flood_watersheds( Array2D<elev_t> &elevations, Array2D<int32_t> &labels, bool alter_elevations ) { grid_cellz_pq<elev_t> open; std::queue<grid_cellz<elev_t> > pit; unsigned long processed_cells = 0; unsigned long pitc = 0, openc = 0; int clabel = 1; //TODO: Thought this was more clear than zero in the results. ProgressBar progress; std::cerr << "\n###Priority-Flood+Watershed Labels" << std::endl; std::cerr << "Setting up boolean flood array matrix..." << std::flush; Array2D<int8_t> closed(elevations.viewWidth(), elevations.viewHeight(), false); std::cerr << "succeeded." << std::endl; std::cerr << "Setting up watershed label matrix..." << std::flush; labels.resize(elevations.viewWidth(), elevations.viewHeight(), -1); labels.setNoData(-1); std::cerr << "succeeded." << std::endl; std::cerr << "The priority queue will require approximately " << (elevations.viewWidth() * 2 + elevations.viewHeight() * 2)*((long)sizeof(grid_cellz<elev_t>)) / 1024 / 1024 << "MB of RAM." << std::endl; std::cerr << "Adding cells to the priority queue..." << std::endl; for (int x = 0; x < elevations.viewWidth(); x++) { open.push_cell(x, 0, elevations(x, 0)); open.push_cell(x, elevations.viewHeight() - 1, elevations(x, elevations.viewHeight() - 1)); closed(x, 0) = true; closed(x, elevations.viewHeight() - 1) = true; } for (int y = 1; y < elevations.viewHeight() - 1; y++) { open.push_cell(0, y, elevations(0, y)); open.push_cell(elevations.viewWidth() - 1, y, elevations(elevations.viewWidth() - 1, y)); closed(0, y) = true; closed(elevations.viewWidth() - 1, y) = true; } std::cerr << "succeeded." << std::endl; std::cerr << "%%Performing Priority-Flood+Watershed Labels..." << std::endl; progress.start(elevations.viewWidth()*elevations.viewHeight()); while (open.size() > 0 || pit.size()>0) { grid_cellz<elev_t> c; if (pit.size() > 0) { c = pit.front(); pit.pop(); pitc++; } else { c = open.top(); open.pop(); openc++; } processed_cells++; //Since all interior cells will be flowing into a cell which has already //been processed, the following line identifies only the edge cells of the //DEM. Each edge cell seeds its own watershed/basin. The result of this will //be many small watersheds/basins around the edge of the DEM. if (labels(c.x, c.y) == labels.noData() && elevations(c.x, c.y) != elevations.noData()) //Implies a cell without a label which borders the edge of the DEM or a region of no_data labels(c.x, c.y) = clabel++; for (int n = 1; n <= 8; n++) { int nx = c.x + dx[n]; int ny = c.y + dy[n]; if (!elevations.in_grid(nx, ny)) continue; if (closed(nx, ny)) continue; //Since the neighbouring cell is not closed, its flow is directed to this //cell. Therefore, it is part of the same watershed/basin as this cell. labels(nx, ny) = labels(c.x, c.y); closed(nx, ny) = true; if (elevations(nx, ny) <= c.z) { if (alter_elevations) elevations(nx, ny) = c.z; pit.push(grid_cellz<elev_t>(nx, ny, c.z)); } else open.push(grid_cellz<elev_t>(nx, ny, elevations(nx, ny))); } progress.update(processed_cells); } std::cerr << "\t\033[96msucceeded in " << progress.stop() << "s.\033[39m" << std::endl; std::cerr << processed_cells << " cells processed. " << pitc << " in pits, " << openc << " not in pits." << std::endl; }
bool Skeleton::buildPositionMatrix(Array2D<float>& pmat) { if (motion_controller == NULL) { char s[1000]; sprintf(s, "AnimSkeleton::buildPositionMatrix failed - skeleton %s has no motion controller", getId()); logout << s << endl; throw AnimationException(s); return false; } // DANGEROUS! - (but this is only special case code) RawMotionController* rawctrl = (RawMotionController*)motion_controller; int num_frames = rawctrl->numFrames(); pmat.resize(num_frames, 3*num_bones); for (int frame=0; frame<num_frames; frame++) { // compute skeletal transform for offsets Matrix4x4 translation_xform = Matrix4x4::translationXYZ(offset_position); Matrix4x4 rotation_xform = Matrix4x4::rotationRPY(offset_rotation); world_xform = translation_xform*rotation_xform; for (short id=0; id<num_bones; id++) { Bone* bone = bone_array[id]; if (bone != NULL) { short bid = bone->getID(); Vector3D p, a; CHANNEL_ID cx(BONE_ID(bid),CT_TX); CHANNEL_ID cy(BONE_ID(bid),CT_TY); CHANNEL_ID cz(BONE_ID(bid),CT_TZ); CHANNEL_ID cpitch(BONE_ID(bid),CT_RX); CHANNEL_ID cyaw(BONE_ID(bid),CT_RY); CHANNEL_ID croll(BONE_ID(bid),CT_RZ); if (rawctrl->isValidChannel(cx)) p.x = rawctrl->getValueByFrame(cx, frame); if (rawctrl->isValidChannel(cy)) p.y = rawctrl->getValueByFrame(cy, frame); if (rawctrl->isValidChannel(cz)) p.z = rawctrl->getValueByFrame(cz, frame); if (rawctrl->isValidChannel(cpitch)) a.pitch = rawctrl->getValueByFrame(cpitch, frame); if (rawctrl->isValidChannel(cyaw)) a.yaw = rawctrl->getValueByFrame(cyaw, frame); if (rawctrl->isValidChannel(croll)) a.roll = rawctrl->getValueByFrame(croll, frame); if (id==0) p += offset_position; bone->setPose(p, a); } } bone_array[0]->update(); // now cycle through bones and record positions for (short id=0; id<num_bones; id++) { Vector3D start, end; getBonePositions(id, start, end); pmat.set(frame, id*3, end.x); pmat.set(frame, id*3+1, end.y); pmat.set(frame, id*3+2, end.z); } } return true; }
void dinf_upslope_area( const Array2D<T> &flowdirs, Array2D<U> &area ){ Array2D<int8_t> dependency; std::queue<GridCell> sources; ProgressBar progress; std::cerr<<"\nA D-infinity Upslope Area"<<std::endl; std::cerr<<"C Tarboton, D.G. 1997. A new method for the determination of flow directions and upslope areas in grid digital elevation models. Water Resources Research. Vol. 33. pp 309-319."<<std::endl; std::cerr<<"p Setting up the dependency matrix..."<<std::endl; dependency.resize(flowdirs); dependency.setAll(0); std::cerr<<"p Setting up the area matrix..."<<std::endl; area.resize(flowdirs); area.setAll(0); area.setNoData(dinf_NO_DATA); bool has_cells_without_flow_directions=false; std::cerr<<"p Calculating dependency matrix & setting noData() cells..."<<std::endl; progress.start( flowdirs.size() ); /////////////////////// //Calculate the number of "dependencies" each cell has. That is, count the //number of cells which flow into each cell. #pragma omp parallel for reduction(|:has_cells_without_flow_directions) for(int y=0;y<flowdirs.height();y++){ progress.update( y*flowdirs.width() ); for(int x=0;x<flowdirs.width();x++){ //If the flow direction of the cell is NoData, mark its area as NoData if(flowdirs.isNoData(x,y)){ area(x,y) = area.noData(); dependency(x,y) = 9; //TODO: This is an unnecessary safety precaution. This prevents the cell from ever being enqueued (an unnecessary safe guard? TODO) continue; //Only necessary if there are bugs below (TODO) } //If the cell has no flow direction, note that so we can warn the user if(flowdirs(x,y)==NO_FLOW){ has_cells_without_flow_directions=true; continue; } //TODO: More explanation of what's going on here 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.inGrid(nlx,nly) && flowdirs(nlx,nly)!=flowdirs.noData() ) dependency(nlx,nly)++; if( flowdirs.inGrid(nhx,nhy) && flowdirs(nhx,nhy)!=flowdirs.noData() ) dependency(nhx,nhy)++; } } std::cerr<<"t Succeeded in = "<<progress.stop()<<" s"<<std::endl; if(has_cells_without_flow_directions) std::cerr<<"W \033[91mNot all cells had defined flow directions! This implies that there will be digital dams!\033[39m"<<std::endl; /////////////////////// //Find those cells which have no dependencies. These are the places to start //the flow accumulation calculation. std::cerr<<"p Locating source cells..."<<std::endl; progress.start( flowdirs.size() ); for(int y=0;y<flowdirs.height();y++){ progress.update( y*flowdirs.width() ); for(int x=0;x<flowdirs.width();x++) if(flowdirs(x,y)==flowdirs.noData()) continue; else if(flowdirs(x,y)==NO_FLOW) continue; else if(dependency(x,y)==0) sources.emplace(x,y); } std::cerr<<"t Source cells located in = "<<progress.stop()<<" s"<<std::endl; /////////////////////// //Calculate the flow accumulation by "pouring" a cell's flow accumulation //value into the cells below it, as indicated by the D-infinite flow routing //method. std::cerr<<"p Calculating up-slope areas..."<<std::endl; progress.start( flowdirs.numDataCells() ); long int ccount=0; while(sources.size()>0){ auto c = sources.front(); sources.pop(); progress.update(ccount++); if(flowdirs.isNoData(c.x,c.y)) //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.inGrid(nhx,nhy) && flowdirs(nhx,nhy)!=flowdirs.noData()) area(nhx,nhy)+=area(c.x,c.y)*phigh; if(n_low!=-1){ nlx = c.x+dinf_dx[n_low]; nly = c.y+dinf_dy[n_low]; if(flowdirs.inGrid(nlx,nly) && flowdirs(nlx,nly)!=flowdirs.noData()){ area(nlx,nly)+=area(c.x,c.y)*plow; if((--dependency(nlx,nly))==0) sources.emplace(nlx,nly); } } if( flowdirs.inGrid(nhx,nhy) && flowdirs(nhx,nhy)!=flowdirs.noData() && (--dependency(nhx,nhy))==0) sources.emplace(nhx,nhy); } std::cerr<<"p Succeeded in = "<<progress.stop()<<" s"<<std::endl; }
void priority_flood_flowdirs(const Array2D<elev_t> &elevations, Array2D<int8_t> &flowdirs) { grid_cellzk_pq<elev_t> open; unsigned long processed_cells = 0; ProgressBar progress; std::cerr << "\n###Priority-Flood+Flow Directions" << std::endl; std::cerr << "Setting up boolean flood array matrix..." << std::flush; Array2D<int8_t> closed(elevations.viewWidth(), elevations.viewHeight(), false); std::cerr << "succeeded." << std::endl; std::cerr << "Setting up the flowdirs matrix..." << std::flush; flowdirs.resize(elevations.viewWidth(), elevations.viewHeight()); flowdirs.setNoData(NO_FLOW); std::cerr << "succeeded." << std::endl; std::cerr << "The priority queue will require approximately " << (elevations.viewWidth() * 2 + elevations.viewHeight() * 2)*((long)sizeof(grid_cellz<elev_t>)) / 1024 / 1024 << "MB of RAM." << std::endl; std::cerr << "Adding cells to the priority queue..." << std::endl; for (int x = 0; x < elevations.viewWidth(); x++) { open.push_cell(x, 0, elevations(x, 0)); open.push_cell(x, elevations.viewHeight() - 1, elevations(x, elevations.viewHeight() - 1)); flowdirs(x, 0) = 3; flowdirs(x, elevations.viewHeight() - 1) = 7; closed(x, 0) = true; closed(x, elevations.viewHeight() - 1) = true; } for (int y = 1; y < elevations.viewHeight() - 1; y++) { open.push_cell(0, y, elevations(0, y)); open.push_cell(elevations.viewWidth() - 1, y, elevations(elevations.viewWidth() - 1, y)); flowdirs(0, y) = 1; flowdirs(elevations.viewWidth() - 1, y) = 5; closed(0, y) = true; closed(elevations.viewWidth() - 1, y) = true; } std::cerr << "succeeded." << std::endl; flowdirs(0, 0) = 2; flowdirs(flowdirs.viewWidth() - 1, 0) = 4; flowdirs(0, flowdirs.viewHeight() - 1) = 8; flowdirs(flowdirs.viewWidth() - 1, flowdirs.viewHeight() - 1) = 6; const int d8_order[9] = { 0,1,3,5,7,2,4,6,8 }; std::cerr << "%%Performing Priority-Flood+Flow Directions..." << std::endl; progress.start(elevations.viewWidth()*elevations.viewHeight()); while (open.size() > 0) { grid_cellz<elev_t> c = open.top(); open.pop(); processed_cells++; for (int no = 1; no <= 8; no++) { int n = d8_order[no]; int nx = c.x + dx[n]; int ny = c.y + dy[n]; if (!elevations.in_grid(nx, ny)) continue; if (closed(nx, ny)) continue; closed(nx, ny) = true; if (elevations(nx, ny) == elevations.noData()) flowdirs(nx, ny) = flowdirs.noData(); else flowdirs(nx, ny) = inverse_flow[n]; open.push_cell(nx, ny, elevations(nx, ny)); } progress.update(processed_cells); } std::cerr << "\t\033[96msucceeded in " << progress.stop() << "s.\033[39m" << std::endl; std::cerr << processed_cells << " cells processed." << std::endl; }