Utilisation d'une meilleure fonction de hachage.

This commit is contained in:
Georges Dupéron 2011-10-02 02:33:51 +02:00
parent 3e1ad07f6e
commit 0a7ea95bd8
6 changed files with 38 additions and 32 deletions

View File

@ -0,0 +1,4 @@
TODO : trouver une fonction unsigned int hash(uint x, uint y) telle que
hash(x,y) renvoie toujours la même chose pour les mêmes x et y, et sans
artefact visuel.

View File

@ -0,0 +1 @@
TODO : faire une interpolation autre que linéaire.

View File

@ -0,0 +1 @@
TODO : Remplir et shade les triangles pour que ça soit plus lisible.

View File

@ -102,10 +102,16 @@ int main() {
// Pour afficher le terrain : // Pour afficher le terrain :
/* int x; */ /* int x; */
/* int y; */ /* int y; */
/* printf("P5 %d %d 255\n", 256, 256); */ /* #define SIZE 256 */
/* for (y = 0; y < 256; y++) { */ /* printf("P5 %d %d 255\n", SIZE, SIZE); */
/* for (x = 0; x < 256; x++) { */ /* for (y = 0; y < SIZE; y++) { */
/* printf("%c", get_z(x, y));//interpolation(256+x, 256+y, 256, 256, 512, 512, 0, 255, 255, 255)); */ /* for (x = 0; x < SIZE; x++) { */
/* //int bit = y / (SIZE/32); */
/* //int h = hash2(t,hash2(x, y)); */
/* //if (y % (SIZE/32) == 0) h = 0; */
/* //printf("%c", ((h >> (31-bit)) & 1) * 255); */
/* //printf("%c", interpolation(256+x, 256+y, 256, 256, 512, 512, 0, 255, 255, 255)); */
/* printf("%c", get_z(x,y)); */
/* } */ /* } */
/* } */ /* } */
return 0; return 0;

49
roam.c
View File

@ -48,27 +48,21 @@ unsigned int getValueForSeed(unsigned int seed) {
return ((seed * primeA) ^ ((seed+1) * primeB)) + seed; // + seed pour éviter d'avoir uniquement des nombres impairs. return ((seed * primeA) ^ ((seed+1) * primeB)) + seed; // + seed pour éviter d'avoir uniquement des nombres impairs.
} }
// Donne des mauvais résultats (en faisant & 0xff…, on obtient des valeurs répétitives). // Ce hash donne des bons résultats sur tous les bits de l'entier
/* unsigned int hash2(unsigned int a, unsigned int b) { */ // généré (pas d'artefacts, répartition homogène des 0 et des 1).
/* unsigned int primeA = 65521; // Plus grand premier < 2^16 */ unsigned int hash2(unsigned int a, unsigned int b) {
/* unsigned int primeB = 4294967291U; // Plus grand premier < 2^32 */ unsigned int h = 1;
/* return ((a * primeA) + (b * primeB) + a + 43) ^ ((a * primeB) + (b * primeA) + b + 57); */
/* } */
int hash2(int a, int b) {
int i; int i;
for (i = 0; i < 5; i++) { // repeat five times for (i = 0; i < 32; i+=8) {
b += a; // b = a + b a *= h;
a *= b; // a = a * (a + b) b *= h;
b ^= a; // b = (a + b) ^ (a * (a + b)) h = h * 65599 + ((a >> i) & 0xff);
a += 211; // a = (a * (a + b)) + 5 h = h * 65599 + ((b >> i) & 0xff);
b /= 2; // b = ((a + b) ^ (a * (a + b))) / 2
} }
return (a >> 3); // high bits are never set… return h;
} }
// Un hachage certes un peu primaire mais bon… unsigned int hash3(unsigned int seed, int x, int y) {
unsigned int hash(unsigned int seed, int x, int y) {
return hash2(seed,hash2(x, y)); return hash2(seed,hash2(x, y));
} }
@ -114,28 +108,27 @@ short** PerlinNoise(Triangle* t) {
// renvoie un z entre 0 et 255 // renvoie un z entre 0 et 255
int get_z(int x, int y) { int get_z(int x, int y) {
unsigned int seed = 45;
x = x; /* Unused */ x = x; /* Unused */
y = y; /* Unused */ y = y; /* Unused */
int z = 0; int z = 0;
int level; int level;
int maxlevel = 7; int maxlevel = 6;
for (level = maxlevel; level > 0; level--) { for (level = maxlevel; level >= 0; level--) {
int step = (1 << level); int step = (1 << level);
int mask = step - 1; int mask = step - 1;
int zmax = mask; int zmax = 2*step - 1;
int x1 = x & ~mask; int x1 = x & ~mask;
int y1 = y & ~mask; int y1 = y & ~mask;
int x2 = x1 + step; int x2 = x1 + step;
int y2 = y1 + step; int y2 = y1 + step;
z += interpolation(x, y, x1, y1, x2, y2, hash(seed, x2, y1) & zmax, hash(seed, x2, y2) & zmax, hash(seed, x1, y2) & zmax, hash(seed, x1, y1) & zmax); z += interpolation(x, y, x1, y1, x2, y2, hash3(level, x2, y1) & zmax, hash3(level, x2, y2) & zmax, hash3(level, x1, y2) & zmax, hash3(level, x1, y1) & zmax);
} }
// ici le résultat est entre 0 (inclues) et 2^(1+maxlevel) (non inclus) // ici le résultat est entre 0 (inclus) et 2^(2+maxlevel) (non inclus)
// On normalise sur [0,256[ sachant que 256 == 2^8 // On normalise sur [0,256[ sachant que 256 == 2^8.
if (maxlevel > 7) if (maxlevel > 6)
z = z >> (-7+maxlevel); z = z >> (-6+maxlevel);
else if (maxlevel != 7) else if (maxlevel != 6)
z = z << (7-maxlevel); z = z << (6-maxlevel);
return z; return z;
} }

1
roam.h
View File

@ -23,4 +23,5 @@ typedef struct Triangle {
Triangle* initDefaultExample(); Triangle* initDefaultExample();
int interpolation(int x, int y, int x1, int y1, int x2, int y2, int ne, int se, int so, int no); int interpolation(int x, int y, int x1, int y1, int x2, int y2, int ne, int se, int so, int no);
unsigned int hash2(unsigned int a, unsigned int b);
int get_z(int x, int y); int get_z(int x, int y);