我看到你的代碼的一些問題:
- 行42:它應該是
double fracY = y-intY;
而不是double fracY = x-intY;
- 您
_noise
功能是對稱的:_noise(x, y) == _noise(y, x)
。該文章使用不是對稱的x+y*57
。
- 快速閱讀the page you mentioned據我所知,
_interpolatedNoise
,_smoothNoise
和_noise
應該採取額外的i
參數。
每次迭代調用不同噪聲函數,通過Noisei表示。
編輯:這是實現2D培林噪聲嘗試:
- 我有改變的
_noise
perlinNoise
爲0和1之間,號碼呼叫所需的實現(見main
)
import 'dart:html';
import 'dart:math' as Math;
class PerlinNoise {
int _octaves;
double _persistence;
Map<int, Map<int, Map<int, double>>> _noises = {};
final _rand = new Math.Random();
PerlinNoise({int octaves: 1, double persistence:1.0}) :
_octaves = octaves,
_persistence = persistence;
double _noise(int i, int x, int y) =>
_noises.putIfAbsent(i,() => {})
.putIfAbsent(x,() => {})
.putIfAbsent(y,() => 2 * _rand.nextDouble() - 1);
double _smoothNoise (int i, int x, int y) {
double corners = (_noise(i, x - 1, y - 1) +
_noise(i, x + 1, y - 1) +
_noise(i, x - 1, y + 1) +
_noise(i, x + 1, y + 1))/16;
double sides = (_noise(i, x - 1, y ) +
_noise(i, x + 1, y ) +
_noise(i, x , y - 1) +
_noise(i, x , y + 1))/8;
double center = _noise(i, x, y)/4;
return corners + sides + center;
}
double _interpolate (double a,double b,double x) {
double ft = x * Math.PI;
double f = (1 - Math.cos(ft)) * 0.5;
return a * (1 - f) + b * f;
}
double _interpolatedNoise (int i, num x, num y) {
int intX = x.floor();
int intY = y.floor();
double fracX = (x - intX).toDouble();
double fracY = (y - intY).toDouble();
double v1 = _smoothNoise(i, intX , intY );
double v2 = _smoothNoise(i, intX + 1, intY );
double v3 = _smoothNoise(i, intX , intY + 1);
double v4 = _smoothNoise(i, intX + 1, intY + 1);
double i1 = _interpolate(v1, v2, fracX);
double i2 = _interpolate(v3, v4, fracX);
return _interpolate(i1, i2, fracY);
}
double perlinNoise(num x, num y) {
var total = 0;
for (var i = 0; i < _octaves; i++) {
int frequency = Math.pow(2, i);
double amplitude = Math.pow(_persistence, i);
total += _interpolatedNoise(i, x * frequency, y * frequency) * amplitude;
}
return total;
}
}
void main() {
PerlinNoise p = new PerlinNoise(octaves: 5, persistence: 0.9);
CanvasElement c = query('canvas');
CanvasRenderingContext2D con = c.context2D;
ImageData id = con.createImageData(1,1);
List d = id.data;
d[3] = 255;
for (var i = 0; i < c.width; i++) {
for (var j = 0; j < c.height; j++) {
// my canvas is 256px x 256px
int val = (128 + 128 * p.perlinNoise(i/256.0, j/256.0)).toInt();
d[0] = val;
d[1] = val;
d[2] = val;
con.putImageData(id, i, j);
}
}
print('done');
}
不錯電子!這讓我更接近實際結果。謝謝!儘管如此,修復並沒有真正給出想要的結果。正如你可能已經注意到的那樣,我試圖用種子來控制隨機化,但是在我的新版本中它看起來並不正確。 新版本:[鏈接](http://tny.cz/d53629ff) – handyface
我用似乎有效的東西更新了答案。歡呼:) –
哇。非常感謝你! – handyface