17.10.2011, 22:44
|
#121
|
Мастер
Регистрация: 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)
|
|