Показать сообщение отдельно
Старый 12.12.2011, 13:50   #2
dsd
Мастер
 
Аватар для dsd
 
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений
(для 1,836 пользователей)
Ответ: Карта высот из картинки

Насчет специальных алгоритмов я не знаю, по моему карта высот она и в Африке карта высот и вся подготовка может быть выполнена в графическом редакторе. А вот по нормалям чутка есть.

        for(int i=0;i<uppersize;i++){
            for(int j=0;j<uppersize;j++){
            int x0=i-1,x1=i+1,y0=j-1,y1=j+1;
            //check of indexes size
            if(i==0){x0=uppersize-1;}
            if(i==uppersize-1){x1=0;}
            if(j==0){y0=uppersize-1;}
            if(j==uppersize-1){y1=0;}
            //normals
            float3  a00(-1,first->seed[x0][y0]-first->seed[i][j],-1); a00.normalize();
            float3  a10(0,first->seed[i][y0]-first->seed[i][j],-1); a10.normalize();
            float3  a20(1,first->seed[x1][y0]-first->seed[i][j],-1); a20.normalize();

            float3  a01(-1,first->seed[x0][j]-first->seed[i][j],0); a01.normalize();
            float3  a11(0,first->seed[i][j]-first->seed[i][j],0); a11.normalize();
            float3  a21(1,first->seed[x1][j]-first->seed[i][j],0); a21.normalize();

            float3  a02(-1,first->seed[x0][y1]-first->seed[i][j],1); a02.normalize();
            float3  a12(0,first->seed[i][y1]-first->seed[i][j],1); a12.normalize();
            float3  a22(1,first->seed[x1][y1]-first->seed[i][j],1); a22.normalize();

            //result normal
            float3 result=a00*a10+a10*a20+a20*a21+a21*a22+a22*a12+a12*a02+a02*a01+a01*a00;result.normalize();
            norm[i][j]=-1*result;
            }}
first->seed[x0][y1] - это моя карта высот там
Плюс даже из гладкой карты высот получится наждачная бумага вместо приличной карты нормалей, но она довольно легко сглаживается gausian blur'ом

            int radius=32;
            gauss_mask=new float*[radius];
            for(int i=0;i<radius;i++){gauss_mask[i]=new float[radius];}
            for(int i=0;i<radius;i++){
                for(int j=0;j<radius;j++){

                    gauss_mask[i][j]=gaussian_blur(i,j, 12.4);

                }}

float gaussian_blur(int x,int y, float sigma)
{

    float koff=(1/sqrt(2*M_PI*pow(sigma,2)))*pow(M_E,-(x*x+y*y)/(2*sigma*sigma));
    return koff;

}

и после построения маски и применения её к изначальной карте нормалей получался более приличный результат.

        for(int i=0;i<uppersize;i++){
        for(int j=0;j<uppersize;j++){
            for(int x=0;x<radius;x++){
            for(int y=0;y<radius;y++){
              //now will sum all here
              if(x==0 && y==0){normb[i][j]=gauss_mask[x][y]*norm[i][j];}
              else if((x==0 && y!=0) ||(x!=0 && y==0)){
              int x0=i-x,x1=i+x,y0=j-y,y1=j+y;
              if(x0<0){x0=uppersize+x0;}
              if(x1>=uppersize){x1=x1-uppersize;}
              if(y0<0){y0=uppersize+y0;}
              if(y1>=uppersize){y1=y1-uppersize;}
              normb[i][j]=normb[i][j]+ 0.5*gauss_mask[x][y]*(norm[x0][y0]+norm[x1][y0]+norm[x0][y1]+norm[x1][y1]);
              }
              else{
              int x0=i-x,x1=i+x,y0=j-y,y1=j+y;
              if(x0<0){x0=uppersize+x0;}
              if(x1>=uppersize){x1=x1-uppersize;}
              if(y0<0){y0=uppersize+y0;}
              if(y1>=uppersize){y1=y1-uppersize;}
              normb[i][j]=normb[i][j]+gauss_mask[x][y]*(norm[x0][y0]+norm[x1][y0]+norm[x0][y1]+norm[x1][y1]);
              }
            }}
          normb[i][j].normalize();
        }}
(Offline)
 
Ответить с цитированием