1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
| #include <iostream>
#include "calque.h"
#include "chunk.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
calque::calque(int t, float p)
{
this->v = new int*[t];
std::cout << "new int" << std::endl;
if(!this->v){
printf("erreur d'alloc");
}
int i,j;
std::cout << "debut boucle" << std::endl;
for (i=0; i<t ; i++){
this->v[i]= new int;
if(!this->v[i]) {
printf("erreur d'alloc");
}
for (j=0; j<t; j++)
this->v[i][j]=0;
}
std::cout << "fin boucle" << std::endl;
this->taille = t;
this->persistance = p;
std::cout << "2" << std::endl;
}
void calque::free_calque(calque* s){
std::cout << "free calque" << std::endl;
int j;
for (j=0; j<s->taille; j++)
free(s->v[j]);
free(s->v);
std::cout << "fin boucle fc" << std::endl;
}
void calque::generer_calque(int frequence,
int octaves,
float persistance,
int liss,
calque *c, int seed){
std::cout << "genCalque" << std::endl;
// itératif
int taille = c->taille;
int i,j,n,f_courante;
int x,y,k,l;
int a;
float pas, sum_persistances;
std::cout << "3" << std::endl;
pas = (float)(taille)/frequence;
float persistance_courante = persistance;
// calque aléatoire
std::cout << "new calque" << std::endl;
calque *random = new calque(taille, 1);
if (!random)
return;
std::cout << "debut boucle rand" << std::endl;
srand(seed);
for (i=0; i<taille; i++)
for (j=0; j<taille; j++)
random->v[i][j] = rand() % 256;
std::cout << "fin boucle rand" << std::endl;
// calques de travail
std::cout << "new calque (travail)" << std::endl;
calque **mes_calques = new calque*;
std::cout << "boucle calques" << std::endl;
for (i=0; i<octaves; i++){
std::cout << "new calque travail" << std::endl;
mes_calques[i] = new calque(taille,persistance_courante);
if (!mes_calques[i])
return;
persistance_courante*=persistance;
}
std::cout << "fin boucle calque travail" << std::endl;
f_courante = frequence;
// remplissage de calque
std::cout << "remplissage calque " << std::endl;
for (n=0; n<octaves; n++){
for(i=0; i<taille; i++)
for(j=0; j<taille; j++) {
a = calque::valeur_interpolee(i, j, f_courante, random);
std::cout << n << i << j << std::endl;
/////////////////////////////////
mes_calques[n]->v[i][j] = a; // CETTE LIGNE
/////////////////////////////////
}
std::cout << "pas crash" << std::endl;
f_courante*=frequence;
}
std::cout << "fin remplissage" << std::endl;
sum_persistances = 0;
for (i=0; i<octaves; i++)
sum_persistances+=mes_calques[i]->persistance;
// ajout des calques successifs
for (i=0; i<taille; i++)
for (j=0; j<taille; j++){
for (n=0; n<octaves; n++)
c->v[i][j]+=mes_calques[n]->v[i][j]*mes_calques[n]->persistance;
// normalisation
c->v[i][j] = c->v[i][j] / sum_persistances;
}
// lissage
calque *lissage;
lissage = new calque(taille, 0);
if(!lissage)
return;
for (x=0; x<taille; x++)
for (y=0; y<taille; y++){
a=0;
n=0;
for (k=x-liss; k<=x+liss; k++)
for (l=y-liss; l<=y+liss; l++)
if ((k>=0) && (k<taille) && (l>=0) && (l<taille)) {
n++;
a+=c->v[k][l];
}
lissage->v[x][y] = (float)a/n;
}
// libération mémoire
free_calque(random);
free_calque(lissage);
for (i=0; i<octaves; i++)
free_calque(mes_calques[i]);
free(mes_calques);
}
int calque::interpolate(int y1, int y2, int n, int delta){
// interpolation non linéaire
if (n==0)
return y1;
if (n==1)
return y2;
float a = (float)delta/n;
float fac1 = 3*pow(1-a, 2) - 2*pow(1-a,3);
float fac2 = 3*pow(a, 2) - 2*pow(a, 3);
return y1*fac1 + y2*fac2;
//////////////////////////////////////////////
// interpolation linéaire
/*if (n!=0)
return y1+delta*((float)y2-(float)y1)/(float)n;
else
return y1;*/
}
int calque::valeur_interpolee(int i, int j, int frequence, calque *r){
// valeurs des bornes
int borne1x, borne1y, borne2x, borne2y, q;
float pas;
pas = (float)r->taille/frequence;
q = (float)i/pas;
borne1x = q*pas;
borne2x = (q+1)*pas;
if(borne2x >= r->taille)
borne2x = r->taille-1;
q = (float)j/pas;
borne1y = q*pas;
borne2y = (q+1)*pas;
if(borne2y >= r->taille)
borne2y = r->taille-1;
int b00,b01,b10,b11;
b00 = r->v[borne1x][borne1y];
b01 = r->v[borne1x][borne2y];
b10 = r->v[borne2x][borne1y];
b11 = r->v[borne2x][borne2y];
int v1 = interpolate(b00, b01, borne2y-borne1y, j-borne1y);
int v2 = interpolate(b10, b11, borne2y-borne1y, j-borne1y);
int fin = interpolate(v1, v2, borne2x-borne1x , i-borne1x);
std::cout << "fin v i " << fin << std::endl;
return fin;
} |
Partager