void ProgResolutionIBW::edgeWidth(const MultidimArray<double> &volCoeffs, const MultidimArray<double> &edges, MultidimArray <double>& widths, const Matrix1D<double> &dir, double step) const { double forward_count, backward_count, slope; Matrix1D<double> pos_aux_fw(3), pos_aux_bw(3), pos(3), pos_aux(3), next_pos(3), Kdir; Kdir=step*dir; //Visit all elements in volume FOR_ALL_ELEMENTS_IN_ARRAY3D(edges) { //Check for border pixels if (A3D_ELEM(edges,k,i,j)!=0) { //reset all counters forward_count=0; backward_count=0; VECTOR_R3(pos_aux_fw,j,i,k); pos_aux_bw=pos=pos_aux_fw; //find out if pixel magnitude grows or decreases pos_aux=pos; pos_aux+=dir; double value_plus_dir=volCoeffs.interpolatedElementBSpline3D(XX(pos_aux),YY(pos_aux),ZZ(pos_aux)); pos_aux=pos; pos_aux-=dir; double value_minus_dir=volCoeffs.interpolatedElementBSpline3D(XX(pos_aux),YY(pos_aux),ZZ(pos_aux)); slope=value_plus_dir-value_minus_dir; double sign; if (slope>0) sign=1; else sign=-1; //current_pixel is multiplied by the sign, so only one condition is enough to detect an //extremum no matter if the pixel values increase or decrease double current_pixel=sign*volCoeffs.interpolatedElementBSpline3D (XX(pos_aux_fw),YY(pos_aux_fw),ZZ(pos_aux_fw)); double next_pixel; bool not_found; //Search for local extremum ahead of the edge in the given direction do { not_found=true; next_pos=pos_aux_fw+Kdir; next_pixel=sign*volCoeffs.interpolatedElementBSpline3D (XX(next_pos),YY(next_pos),ZZ(next_pos)); if(next_pixel>current_pixel) { current_pixel=next_pixel; pos_aux_fw=next_pos; forward_count++; } else { not_found=false; } } while(not_found); current_pixel=sign*volCoeffs.interpolatedElementBSpline3D (XX(pos_aux_bw),YY(pos_aux_bw),ZZ(pos_aux_bw)); //Search for local extremum behind of the edge in the given direction do { not_found=true; next_pos=pos_aux_bw-Kdir; next_pixel=sign*volCoeffs.interpolatedElementBSpline3D (XX(next_pos),YY(next_pos),ZZ(next_pos)); if(next_pixel<current_pixel) { current_pixel=next_pixel; pos_aux_bw=next_pos; backward_count++; } else { not_found=false; } } while(not_found); //If the width found for this position is smaller than the one stores in edges volume //before it is overwritten if ((forward_count+backward_count)<A3D_ELEM(widths,k,i,j)) { A3D_ELEM(widths,k,i,j)=forward_count+backward_count; } } } }
sf::Vector2f Colisionable::evalCollisions(sf::Vector2f posOld, sf::Vector2f posNew, sf::Vector2f size){ /* float dist= sqrt((posNew.x-posOld.x)*(posNew.x-posOld.x)+(posNew.y-posOld.y)*(posNew.y-posOld.y)); while(dist>Settings::TILE_SIZE){ sf::Vector2f posOldOld = posOld; float ratio = (Settings::TILE_SIZE-1)/dist; sf::Vector2f newPosAux(((1-ratio)*posOld.x+ratio*posNew.x),((1-ratio)*posOld.y+ratio*posNew.y)); posOld = evalCollisions(posOld,newPosAux,size); if(posOldOld == posOld) return posOld; dist= sqrt((posNew.x-posOld.x)*(posNew.x-posOld.x)+(posNew.y-posOld.y)*(posNew.y-posOld.y)); }*/ sf::Vector2f pos_aux(posNew.x, posNew.y); sf::Vector2f size_aux(size.x, size.y); Map* map = Scene::getScene()->getMap(); Tile* firstT = map->getTile(pos_aux.x, pos_aux.y, 1); Tile* lastT = map->getTile(pos_aux.x+size_aux.x, pos_aux.y+size_aux.y, 1); if(firstT != nullptr && lastT != nullptr){ col_bottom = 0; col_top = 0; col_left = 0; col_right = 0; col_bottom_dist = 0; col_top_dist = 0; col_left_dist = 0; col_right_dist = 0; std::vector<Tile*> tiles_col = map->getTilesCol(pos_aux, size_aux); //std::cout << "number of cols" << tiles_col._size() << std::endl; //std::cout << "lel" << std::endl; for(int i = 0; i< tiles_col.size(); ++i){ // //comproba colisions Tile* t = tiles_col[i]; sf::Vector2f tile_size(t->getWidth(), t->getHeight()); FixColision(pos_aux, size_aux, t->GetPosition(), tile_size); } bool valid_move = true; if(bool(col_bottom) + bool(col_left) + bool(col_right) + bool(col_top) >=3) valid_move = false; if(abs(posNew.x-posOld.x) > Settings::TILE_SIZE*3 || abs(posNew.y-posOld.y) > Settings::TILE_SIZE*3) { //float dist= sqrt((posNew.x-posOld.x)*(posNew.x-posOld.x)+(posNew.y-posOld.y)*(posNew.y-posOld.y)); valid_move = false; } if(col_bottom >= col_top){ col_top = 0; posNew.y = posNew.y - col_bottom_dist; } else{ col_bottom = 0; posNew.y = posNew.y + col_top_dist; } if(col_left >= col_right){ col_right = 0; posNew.x = posNew.x + col_left_dist; } else{ col_left = 0; posNew.x = posNew.x - col_right_dist; } if(valid_move) return posNew; else { return evalCollisions(sf::Vector2f(posOld.x,posOld.y-32),sf::Vector2f(posOld.x,posOld.y-32),size); } } return posOld; }