Bonjour à tous,

Je fais un projet de générateur de Heightmaps en C#, mais il y a un problème avec l'image générée. En effet, il y a des "glitchs" qui apparaissent, comme si on voyait la structure des différents "carrés" et "diamants" de l'algorithme. Faute de mieux, j'ai adapté le code source donné dans cet article directement en C#.

Une image valant mieux que mille mots, voici une des heightmaps incriminées :



Le code écrit est le suivant (c'est un projet WinForm) :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
 
namespace Diamond_Square
{
    class DiamondSquare
    {
        private float[,] vectPoints;
        private int size;
        private float variability;
        private float spacing;
        private float min;
        private float max;
        private bool filled;
        private Random rnd;
 
        private const int PIXEL_SIZE = 3;
 
        public DiamondSquare(int steps, float variability, float spacing)
        {
            size = (1 << steps) + 1;
            this.variability = variability;
            this.spacing = spacing;
            rnd = new Random();
            filled = true;
            vectPoints = new float[size, size];
        }
 
        private float Randomize()
        {
            const int limit = 1000000;
            return (float)(rnd.Next() % limit) / limit;
        }
 
        private float DiamondStep(int x, int y, int halfSpacing)
        {
            float sum = 0f;
            int n = 0;
 
            if ((x >= halfSpacing) && (y >= halfSpacing))
            {
                sum += vectPoints[x - halfSpacing, y - halfSpacing];
                n++;
            }
 
            if ((x >= halfSpacing) && (y + halfSpacing < size))
            {
                sum += vectPoints[x - halfSpacing, y + halfSpacing];
                n++;
            }
 
            if ((x + halfSpacing < size) && (y >= halfSpacing))
            {
                sum += vectPoints[x + halfSpacing, y - halfSpacing];
                n++;
            }
 
            if ((x + halfSpacing < size) && (y + halfSpacing < size))
            {
                sum += vectPoints[x + halfSpacing, y + halfSpacing];
                n++;
            }
 
            return sum / n;
        }
 
        private float SquareStep(int x, int y, int halfSpacing)
        {
            float sum = 0f;
            int n = 0;
 
            if (x >= halfSpacing)
            {
                sum += vectPoints[x - halfSpacing, y];
                n++;
            }
 
            if (x + halfSpacing < size)
            {
                sum += vectPoints[x + halfSpacing, y];
                n++;
            }
 
            if (y >= halfSpacing)
            {
                sum += vectPoints[x, y - halfSpacing];
                n++;
            }
 
            if (y + halfSpacing < size)
            {
                sum += vectPoints[x, y + halfSpacing];
                n++;
            }
 
            return sum / n; 
        }
 
        public void Generate(float leftBottom = 0f, float leftTop = 0f, float rightTop = 0f, float rightBottom = 0f)
        {
            vectPoints[0, 0] = leftBottom;
            vectPoints[0, size - 1] = rightBottom;
            vectPoints[size - 1, 0] = leftTop;
            vectPoints[size - 1, size - 1] = rightTop;
 
            int spacing = size - 1;
 
            while (spacing > 1)
            {
                int halfSpacing = spacing / 2;
 
                for (int x = halfSpacing; x < size; x += spacing)
                {
                    for (int y = halfSpacing; y < size; y += spacing)
                    {
                        vectPoints[x, y] = DiamondStep(x, y, halfSpacing) + Randomize() * spacing * variability;
                    }
                }
 
                for (int x = 0; x < size; x += halfSpacing)
                {
                    int yStart = ((x / halfSpacing) % 2 == 0) ? halfSpacing : 0;
 
                    for (int y = yStart; y < size; y += spacing)
                    {
                        vectPoints[x, y] = SquareStep(x, y, halfSpacing) + Randomize() * spacing * variability;
                    }
                }
 
                spacing = halfSpacing;
            }
 
            max = vectPoints[0, 0];
            min = vectPoints[0, 0];
 
            for (int x = 0; x < size - 1; x++)
            {
                for (int y = 0; y < size - 1; y++)
                {
                    if (vectPoints[x, y] > max)
                    {
                        max = vectPoints[x, y];
                    }
 
                    if (vectPoints[x, y] < min)
                    {
                        min = vectPoints[x, y];
                    }
                }
            }
        }
 
        public void Draw(Graphics graphics)
        {
            for (int x = 0; x < size - 1; x++)
            {
                for (int y = 0; y < size - 1; y++)
                {
                    if (filled)
                    {
                        graphics.FillRectangle(new SolidBrush(Color.FromArgb((int)(vectPoints[x, y]), (int)(vectPoints[x, y]), (int)(vectPoints[x, y]))), x * PIXEL_SIZE, y * PIXEL_SIZE, PIXEL_SIZE, PIXEL_SIZE);
                    }
                }
            }
        }
    }
}
La classe est instanciée et appelée depuis le formulaire principal et l'image est dessinée dans une PictureBox. Pour information, les valeurs transmises au constructeur de l'objet de type DiamondSquare sont respectivement 6, 0.5 et 2.0.

J'ai beau chercher, je ne vois pas d'où vient le problème