书名:代码本色:用编程模拟自然系统
作者:Daniel Shiffman
译者:周晗彬
ISBN:978-7-115-36947-5
0.6.1 映射噪声
1、如何处理得到的噪声值
我们开始研究如何处理得到的噪声值。
- 得到0~1的噪声值之后,我们需要将它映射到我们想要的范围内
- 最方便的方法是使用Processing的map()函数。
map()函数有5个参数。
第一个参数是我们想要映射的值(这里即n),
后面的两个参数是该值原来的范围(最大值和最小值),
最后两个参数是目标范围。
2、映射
我们知道噪声函数的返回值在0~1的范围内,但我们想要在0到窗口宽度的范围内画这个圆。
float t = 0;
void draw() {
float n = noise(t);
float x = map(n,0,1,0,width); 用map()函数定制Perlin噪声的范围
ellipse(x,180,16,16);
t += 0.01;
}
3、Perlin噪声游走模型
class Walker {
float x, y;
float tx, ty;
float prevX, prevY;
Walker() {
tx = 0;
ty = 10000;
x = map(noise(tx), 0, 1, 0, width);
y = map(noise(ty), 0, 1, 0, height);
}
void render() {
stroke(255);
line(prevX, prevY, x, y);
}
// Randomly move according to floating point values
void step() {
prevX = x;
prevY = y;
x = map(noise(tx), 0, 1, 0, width);
y = map(noise(ty), 0, 1, 0, height);
tx += 0.01;
ty += 0.01;
}
}
- 请注意上面的例子是如何使用tx和ty这对变量做参数的。
我们同时需要跟踪两个时间变量,一个用于产生游走对象的x坐标,另一个用于产生y坐标,
但是这两个变量还有一些奇怪的地方,为什么tx从0开始,而ty从10 000开始?
尽管这两个初始值是随意确定的,但我们故意用了不同的值来初始化这两个时间变量。
这是因为噪声函数的返回结果是确定的:无论何时调用它,只要传入的时间点t相同,返回的结果也相同。
如果我们通过同一个时间点t获取两个坐标,返回的x坐标和y坐标会是相等的,这意味着游走对象Walker只会在一条对角线上移动。
在这里,我们用了噪声空间的两个不同区域,x坐标对应的区域从0开始,y坐标对应的区域从10 000开始,这样x坐标和y坐标就会彼此独立。
- 实际上,Perlin噪声是没有时间轴这个概念的。
为了让大家更容易地理解噪声函数的工作方式,我引入了时间轴这个隐喻。但是,我们应该有空间的概念,而不该有时间轴的概念。
上图描述了噪声序列在一维空间上的排列,我们可以获取任意x坐标上的噪声值。
比如,你经常会在噪声图中看到一个叫xoff的变量,它表示x轴上的偏移量,取代上面说的时间点变量t(见图表注解)。