Тема: Странное.
Показать сообщение отдельно
Старый 17.10.2011, 22:44   #121
dsd
Мастер
 
Аватар для dsd
 
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений
(для 1,836 пользователей)
шум перлина


прикола ради написал це
Handle perlin_noise(int seed, int size){
srand(seed);
int resolution=1<<size;
printf("\n resolution %d",resolution);
//создание структуры данных
double **m[size];
for(int i=0;i<size;i++){
int width=1<<(i+1);
m[i]=new double*[width];
for(int j=0;j<width;j++){m[i][j]=new double[width];}
printf("\n %d",width);
}
//заполнение структуры шумом
for(int i=0;i<size;i++){
    int width=1<<(i+1);
    for(int j=0;j<width;j++){for(int k=0;k<width;k++){m[i][j][k]=(1-2*(double)rand()/RAND_MAX)/(width>>1);}}}

//суммирование шума
for(int i=0;i<resolution;i++){for(int j=0;j<resolution;j++){
    double val=0;
        for(int k=0;k<size;k++){
        //нулевой массив шириной 2 ячейки
        int width=2<<k;
        double vi=width*i/resolution;// что оно мне считает? О_о
        double hi=width*j/resolution;// что оно мне считает? О_о
            //так индексы
        int x0=floor(vi);
        int x1=ceil(vi);
        double deltax=vi-x0;
        int y0=floor(hi);
        int y1=ceil(hi);
        double deltay=hi-y0;
        //теперь вычисление приближенного значения
        //косяк тута в формуле.
        val=val+((m[k][x0][y0]*deltax+m[k][x1%width][y0]*(1-deltax))*deltay+(m[k][x0][y1%width]*deltax+m[k][x1%width][y1%width]*(1-deltax))*(1-deltay));
        }
        m[size-1][i][j]=val; }}
//приведение в интервал (0,1)
double min=100000.01;
double max=-100000.01;
for(int i=0;i<resolution;i++){for(int j=0;j<resolution;j++){
if(m[size-1][i][j]>max){max=m[size-1][i][j];}
if(m[size-1][i][j]<min){min=m[size-1][i][j];}
}}
double length=max-min;
for(int i=0;i<resolution;i++){for(int j=0;j<resolution;j++){
m[size-1][i][j]=(m[size-1][i][j]-min)/length;
}}
//рисование текстуры
Handle tex=xCreateTexture(resolution,resolution);
xSetBuffer(xTextureBuffer(tex));
xLockBuffer(xTextureBuffer(tex));
for (int i=0;i<resolution;i++){
    for (int j=0;j<resolution;j++){
        double val=pow(m[size-1][i][j],2);
        xWritePixelFast(i,j,ARGB(255,255*val,255*val,255*val),xTextureBuffer(tex));}}
xSetBuffer(xBackBuffer());
xUnlockBuffer(xTextureBuffer(tex));

return tex;

}
пошел курить алгоритмы сглаживания


)


результат обоих кусков идентичен, а вот время различается сильно
val=val+((m[k][x0][y0]*deltax+m[k][x1%width][y0]*(1-deltax))*deltay+(m[k][x0][y1%width]*deltax+m[k][x1%width][y1%width]*(1-deltax))*(1-deltay)); 
        //можно посчитать четыре прямые через вершины и усреднить итоговую сумму.
      /*double val00=m[k][x0][y0];
        double val01=m[k][x1%width][y0];
        double val10=m[k][x0][y1%width];
        double val11=m[k][x1%width][y1%width];*/
        //вычисление точек на краях, точка может быть вне границы квадрата, но это пох.
        //прямая через две точки
        //  |x2-x1  y2-y1|
        //  |x -x1  y -y1|=0
        // уравнение прямой (x2-x1)(y-y1)-(x-x1)(y2-y1)=0
        //y=x(y2-y1)/(x2-x1)+y1-x1(y2-y1)/(x2-x1)
        //точка 0,0  и deltax,deltay ищу точку на этой прямой с координатой x=1
        double x=1;
        double x1=0;
        double y1=0;
        double x2=deltax;
        double y2=deltay;
        double y=x*(y2-y1)/(x2-x1)+y1-x1*(y2-y1)/(x2-x1);
        int ymin=floor(y);
        int ymax=ceil(y);
        double val00=(m[k][x00][ymin%width]*(ymax-ymin)+m[k][x00][ymax%width]*(1-ymax+ymin)-m[k][x00][y00])*deltax+m[k][x00][y00];
        //точка 0,1  и deltax,deltay ищу точку на этой прямой с координатой x=1
        x=1;
        x1=0;
        y1=1;
        y=x*(y2-y1)/(x2-x1)+y1-x1*(y2-y1)/(x2-x1);
        //индекс у значений x01 а игрек
        ymin=floor(y);
        ymax=ceil(y);
        double val01=(m[k][x10][ymin%width]*(ymax-ymin)+m[k][x10][ymax%width]*(1-ymax+ymin)-m[k][x00][y10])*deltax+m[k][x00][y10];

        //точка 1,0  и deltax,deltay ищу точку на этой прямой с координатой x=0
        x=0;
        x1=1;
        y1=0;
        y=x*(y2-y1)/(x2-x1)+y1-x1*(y2-y1)/(x2-x1);
        ymin=floor(y);
        ymax=ceil(y);
        double val10=(m[k][x00][ymin%width]*(ymax-ymin)+m[k][x00][ymax%width]*(1-ymax+ymin)-m[k][x10][y00])*(1-deltax)+m[k][x10][y00];

        //точка 1,1  и deltax,deltay ищу точку на этой прямой с координатой x=0
        x=0;
        x1=1;
        y1=1;
        y=x*(y2-y1)/(x2-x1)+y1-x1*(y2-y1)/(x2-x1);
        ymin=floor(y);
        ymax=ceil(y);
        double val11=(m[k][x10][ymin%width]*(ymax-ymin)+m[k][x10][ymax%width]*(1-ymax+ymin)-m[k][x10][y10])*(1-deltax)+m[k][x10][y10];

        //прямая через две точки
        //  |x2-x1  y2-y1|
        //  |x -x1  y -y1|=0
        // уравнение прямой (x2-x1)(y-y1)-(x-x1)(y2-y1)=0
        //y*(x2-x1)=x(y2-y1)+y1*(x2-x1)-x1(y2-y1)
        //x=y1*(x2-x1)/(y2-y1)-x1-y*(x2-x1)/(y2-y1)
        //точка 0,0  и deltax,deltay ищу точку на этой прямой с координатой y=1
        y=1;
        x1=0;
        y1=0;
        x2=deltax;
        y2=deltay;
        x=y1*(x2-x1)/(y2-y1)-x1-y*(x2-x1)/(y2-y1);
        ymin=floor(x);
        ymax=ceil(x);
        double val100=(m[k][ymin%width][y00]*(ymax-ymin)+m[k][ymax%width][y00]*(1-ymax+ymin)-m[k][x00][y00])*deltay+m[k][x00][y00];
        //точка 0,1  и deltax,deltay ищу точку на этой прямой с координатой y=1
        y=1;
        x1=0;
        y1=1;
        x=y1*(x2-x1)/(y2-y1)-x1-y*(x2-x1)/(y2-y1);
        //индекс у значений x01 а игрек
        ymin=floor(y);
        ymax=ceil(y);
        double val101=(m[k][ymin%width][y10]*(ymax-ymin)+m[k][ymax%width][y10]*(1-ymax+ymin)-m[k][x00][y10])*(1-deltay)+m[k][x00][y10];

        //точка 1,0  и deltax,deltay ищу точку на этой прямой с координатой x=0
        y=0;
        x1=1;
        y1=0;
        x=y1*(x2-x1)/(y2-y1)-x1-y*(x2-x1)/(y2-y1);
        ymin=floor(y);
        ymax=ceil(y);
        double val110=(m[k][ymin%width][y00]*(ymax-ymin)+m[k][ymax%width][y00]*(1-ymax+ymin)-m[k][x10][y00])*deltay+m[k][x10][y00];

        //точка 1,1  и deltax,deltay ищу точку на этой прямой с координатой x=0
        y=0;
        x1=1;
        y1=1;
        x=y1*(x2-x1)/(y2-y1)-x1-y*(x2-x1)/(y2-y1);
        ymin=floor(y);
        ymax=ceil(y);
        double val111=(m[k][ymin%width][y10]*(ymax-ymin)+m[k][ymax%width][y10]*(1-ymax+ymin)-m[k][x10][y10])*(1-deltay)+m[k][x10][y10];

        //сумма
        val=val+0.125*(val00+val01+val10+val11+val100+val101+val110+val111);

Последний раз редактировалось dsd, 13.12.2011 в 22:59.
(Offline)
 
Ответить с цитированием
Эти 2 пользователя(ей) сказали Спасибо dsd за это полезное сообщение:
Mr_F_ (18.10.2011), Randomize (18.10.2011)