2011-07-06 3 views
4

J'essaye d'implémenter le Noise amélioré dans mon jeu XNA, mais ma fonction Noise améliorée continue à renvoyer 0.0f. C'est exactement le même code que celui de Ken Perlin (http://mrl.nyu.edu/~perlin/noise/), juste porté sur C#.La version de Noise améliorée continue à renvoyer 0

J'ai essayé de réécrire la classe et même copier et coller directement sur le site (et le portage vers C#, bien sûr), mais il ne veut pas une valeur de sortie, mais 0.

Voici le code que j'utilise:

public class PerlinNoise 
    { 
     private int[] permutations = new int[512]; 

    private Random random; 

    public PerlinNoise() 
     : this(Environment.TickCount) 
    { } 

    public PerlinNoise(int seed) 
    { 
     random = new Random(seed); 

     for (int i = 0; i < 256; i++) 
     { 
      permutations[i] = i; 
     } 

     for (int i = 0; i < 256; i++) 
     { 
      int k = random.Next(256 - i) + i; 

      int l = permutations[i]; 

      permutations[i] = permutations[k]; 
      permutations[k] = l; 
      permutations[i + 256] = permutations[i]; 
     } 
    } 

    private int fastfloor(float x) 
    { 
     return x > 0 ? (int)x : (int)x - 1; 
    } 

    private float fade(float t) 
    { 
     return t * t * t * (t * (t * 6 - 15) + 10); 
    } 

    private float lerp(float t, float a, float b) 
    { 
     return a + t * (b - a); 
    } 

    public float grad(int hash, float x, float y, float z) 
    { 
     int h = hash & 15; 

     float u = h < 8 ? x : y, 
      v = h < 4 ? y : h == 12 || h == 14 ? x : z; 

     return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v); 
    } 

    public float noise3d(float x, float y, float z) 
    { 
     int X = fastfloor(x) & 0xff, 
      Y = fastfloor(y) & 0xff, 
      Z = fastfloor(z) & 0xff; 

     x -= fastfloor(x); 
     y -= fastfloor(y); 
     z -= fastfloor(z); 

     float u = fade(x); 
     float v = fade(y); 
     float w = fade(z); 

     int A = permutations[X] + Y, AA = permutations[A] + Z, AB = permutations[A + 1] + Z, 
      B = permutations[X + 1] + Y, BA = permutations[B] + Z, BB = permutations[B + 1] + Z; 

     return lerp(w, lerp(v, lerp(u, grad(permutations[AA], x, y, z), 
           grad(permutations[BA], x - 1, y, z)), 
         lerp(u, grad(permutations[AB], x, y - 1, z), 
           grad(permutations[BB], x - 1, y - 1, z))), 

         lerp(v, lerp(u, grad(permutations[AA + 1], x, y, z - 1), 
           grad(permutations[BA + 1], x - 1, y, z - 1)), 
         lerp(u, grad(permutations[AB + 1], x, y - 1, z - 1), 
           grad(permutations[BB + 1], x - 1, y - 1, z - 1)))); 
    } 

    public float noise2d(float x, float y) 
    { 
     return noise3d(x, y, 0f); 
    } 
} ` 

Pour le tester, je l'ai fait simplement:

string[] args = Console.ReadLine().Split(' '); 

PerlinNoise noise = new PerlinNoise(); 

int x = args[0]; 
int y = args[1]; 
int z = args[2]; 

Console.WriteLine(noise.noise3d(x, y, z)); 

Et comme je le disais plus haut, il y aura toujours sortie 0.

Répondre

1

Il semble sortir 0.0f si tous les arguments sont des nombres entiers. Modifiez votre code de test pour

var input = Console.ReadLine() 
        .Split(' ') 
        .Select(s => float.Parse(s, 
         System.Globalization.CultureInfo.InvariantCulture)) 
        .ToArray(); 

et essayer d'entrer, par exemple, 4234.2123 3123.12312 423.2434.

Je ne suis pas sûr si ce comportement est souhaité, mais

 x -= Math.Floor(x);        // FIND RELATIVE X,Y,Z 
     y -= Math.Floor(y);        // OF POINT IN CUBE. 
     z -= Math.Floor(z); 

fera toujours x, y & z = 0 si elles sont des nombres entiers; fade(0.0f) est également toujours zéro.

+0

Malheureusement, il renverra toujours 0, sauf si les valeurs sont décimales ou très extrêmes. Puisque je n'utiliserai que Perlin Noise pour les coordonnées intégrales, cela ne fonctionnera pas exactement pour moi. – user830713

1

Multipliez vos entrées par (1/MAX_VALUE) dans votre boîte d'entrée, multipliez par 1/256 ou plus, et ne lui donnez jamais rien de plus grand que cela. Lorsque vous utilisez votre jeu, multipliez l'entrée par (1/MAXIMUM_CHOORD_VALUE).

Questions connexes