Example #1
0
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;
            }
        }
    }
}
Example #2
0
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;
}