제목에 Perlin Noise를 사용하여 Heightmap Generator를 만들고 있습니다. >http://freespace.virgin.net/hugo.elias/models/m_perlin.htmPerlin을 사용하는 Heightmap Generation 노이즈가 검은 비트 맵을 반환합니다.
및 C# 코드에 설정 -
이 사이트에서 의사 코드를 사용했습니다. 지금까지 모든 변수 유형 할당을 수행했으며 코드는 출력을 제공합니다. 불행히도 내 출력은 다음과 같습니다. ->
오른쪽에서 볼 수 있듯이 오른쪽과 아래쪽 가장자리는 검은 색에서 흰색으로 약간 그라데이션이 있지만 나머지 모든 것은 검은 색입니다.
여기 내 C# 소스입니다 - 누구에게의를 원하는 경우>
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;
}
return total;
}
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;
}
도 내가 우편의 비주얼 스튜디오 솔루션을 업로드 할 수 있습니다.
지금까지 Noise() 함수가 잘못되었음을 알았습니다. 왜냐하면 -0,281을 반환하기 때문에 ... 가장 많은 시간입니다. -1.0에서 1.0 사이의 부동 소수점 숫자를 반환해야합니다. 다른 무작위 기능으로 시도했지만 출력은 매번 똑같습니다.
당신이 나를 도울 수 있기를 바랍니다. 그리고 anny 제안을 위해 thx.
나는 0x7fffffff를 의미한다고 생각합니다. 즉, C#의 내장 Random 클래스를 대신 사용해보십시오. – redtuna
또한 0x7fffffff로 시도했지만 그 결과는 같습니다. 알다시피, 거의 모든 프로그래밍 언어에서 모든 무작위 클래스의 모든 빌드는 최대 값과 최소값에서 100 % 무작위가 아닙니다 ... min & max 사이의 값은 generatet 많은 oftener 다음 min & 맥스 ... – Ace
에이스, 그건 이상한 일입니다 - 당신이 그것을 확인할 수 있었습니까? 물론 확정적 함수는 100 % 무작위가 될 수는 없지만 의사 난수 함수가 손상 되었다면 자체적으로 교체하기 전에 먼저 내장 함수를 시도하는 것이 합리적입니다. – redtuna