# 使用Perlin Noise生成高度图会返回黑色位图Heightmap Generation using Perlin Noise returns black bitmap

``````    private void button1_Click( object sender, EventArgs e ) {
persistence = float.Parse( textBox4.Text );
NumberOfOctaves = Int32.Parse( textBox5.Text );

int width = Int32.Parse( textBox1.Text );
int height = Int32.Parse( textBox2.Text );
float zoom = float.Parse( textBox3.Text );

generate( width, height, zoom );
}

public float Noise( int x, int y ) {
long n = x + ( y * 57 );
n = ( long )Math.Pow( ( n << 13 ), n );
return ( float )( 1.0 - ( ( n * ( n * n * 15731 + 789221 ) + 1376312589 ) & 0x7fffffff ) / 1073741824.0 );
}

public float SmoothNoise( float x, float y ) {
float corners = ( Noise((int) (x-1), (int) (y-1)) + Noise((int) (x+1), (int) (y-1)) + Noise((int) (x-1), (int) (y+1)) + Noise((int) (x+1), (int) (y+1)) ) / 16;
float sides   = ( Noise((int) (x-1), (int) y) + Noise((int) (x+1), (int) y) + Noise((int) x, (int) (y-1)) + Noise((int) x, (int) (y+1)) ) /  8 ;
float center  =  Noise( (int)x, (int)y ) / 4;
return corners + sides + center;
}

public float CosineInterpolate( float a, float b, float x ) {
double ft = x * 3.1415927;
double f = ( 1 - Math.Cos( ft ) ) * 0.5;

return (float)( ( a * ( 1 - f ) ) + (b * f) );
}

public float InterpolatedNoise( float x, float y ) {
// MessageBox.Show( x.ToString() );
int intX = ( int )x;
float fractX = x - intX;

int intY    = ( int ) y;
float fractY = y - intY;

float v1 = SmoothNoise(intX,     intY);
float v2 = SmoothNoise(intX + 1, intY);
float v3 = SmoothNoise(intX,     intY + 1);
float v4 = SmoothNoise(intX + 1, intY + 1);

float i1 = CosineInterpolate(v1 , v2 , fractX);
float i2 = CosineInterpolate(v3 , v4 , fractX);

// MessageBox.Show( intX + "\n" + intY + "\n" + fractX + "\n" + fractY + "\n" + v1 + "\n" + v2 + "\n" + v3 + "\n" + v4 + "\n" + i1 + "\n" + i2 + "\n" + CosineInterpolate( i1, i2, fractY ) );

return CosineInterpolate(i1 , i2 , fractY);
}

public float PerlinNoise2D( float x, float y ) {
float total = 0;
float p = persistence;
int n = NumberOfOctaves;

for(int i = 0; i < n; i++ ) {
int frequency = (int)Math.Pow( 2, i );
// MessageBox.Show( Math.Pow( 2, i ).ToString() );
float amplitude = ( int )Math.Pow( p, i );
total = total + InterpolatedNoise(x * frequency, y * frequency) * amplitude;
}
}

private void generate( int sizeX, int sizeY, float zoom ) {
int zoomX = (int)( sizeX * zoom );
int zoomY = (int)( sizeY * zoom );

float max = int.MinValue;
float min = int.MaxValue;

float[,] nmap = new float[zoomX,zoomY];

Bitmap heightMap = new Bitmap(zoomX,zoomY);

for (int x=0; x<zoomX; x++) {
for (int y=0; y<zoomY; y++) {
// MessageBox.Show( PerlinNoise2D( x / zoom, y / zoom ).ToString() );

nmap[x,y] = PerlinNoise2D(x/zoom,y/zoom);
max = (max < nmap[x,y]) ? nmap[x,y] : max;
min = (min > nmap[x,y]) ? nmap[x,y] : min;
}
}

max = max-min;

for (int x=0; x<zoomX;x++) {
for (int y=0; y<zoomY;y++) {
int calc = (int) ( (nmap[x,y] - min) / max );
heightMap.SetPixel(x,y,Color.FromArgb(calc,calc,calc));
}
}

pictureBox1.Image = heightMap;
}
``````

## 1 个回复1

### ===============>>#1 票数：2

``````n = ( long )Math.Pow( ( n << 13 ), n );
``````

``````n = ( long )(( n << 13 ) ^ n);
``````

``````int calc = (int) ( (nmap[x,y] - min) / max );
``````

``````int calc = (int) (( (nmap[x,y] - min) / max ) * 255);
``````