代码本色——雪梨的Processing探索·Chapter 0:随机游走

概述

Chapter 0为我们介绍了随机数概率噪声在运动当中起到的变化作用,下面就让我们来好好的了解下这些数学名词,究竟可以起到怎样的公用,最后再让我们来发挥想象进行这些知识的运用创作。

原理介绍

随机数

提起随机数,编程做的多的同学都能想起来一个关键词,Random(或是Rand),想想Unity&C#里面障碍物的随机选择(Random.Range),Matlab里面为了产生噪声的各种分布随机数生成器(binornd,unidrnd等等),之前我们在p5.js的码绘当中使用过,用于给出心形的产生位置。而在《代码本色》的作者Daniel的叙述下,随机数可以用作物体运动位置的决定因素,你可以用随机数直接生成一个物体所在的位置,但这种手法,未免使得物体运动太过飘渺不定(毕竟也不是《X战警》里的夜行者和闪烁,瞬移有点过分了!!咳咳~)。那么如果想要创造出一种随机连续运动的状态,我们要如何联系随机数呢,答案就是:用随机数决定你下一步的方向。根据作者对于抛硬币行为的类比,我们不妨这样想,投掷一个骰子,你有可能获得6种结果,这六种结果,分别决定你是向上、下、左、右、前、后迈一步,那么在这里,骰子就好比一个随机数生成器,帮助我们决定了方向前进。

在Processing的绘制当中,我们引入Walker对象的概念,用来作为我们游走的主体,利用两轮随机数选择,分别选出在x轴或是y轴上前进的三个方向(-1,0,1),代码块如下:

void step()
 {
       
 	int stepx = int(random(3))-1;        
 	int stepy = int(random(3))-1;   
  	x += stepx;   
  	y += stepy; 
 } 

这里我们引入了3*3区域的划分,来保证我们可以走到屏幕上任何一个像素。
在这里插入图片描述
当然如果想要我们的运动变化更加多样,也可以将上述step函数中的取整部分换成浮点数:

void step()
 {
     
	float stepx = random(-1, 1); 
	float stepy = random(-1, 1);   
	x += stepx;   
	y += stepy; 
} 

概率

提起这个名词,所有的人都会非常熟悉(比如肖战有多大可能性去某某节目的录制),在Processing里我们可以有更多不同的发现。如果看了书上的例子,就会发现如果是random函数的数据生成,它会是均匀生成的,也就是说,每一个运动方向,Walker对象的前进都是等可能的:在这里插入图片描述
那么如果我想让Walker有偏向的前进呢(比如从左游荡到右),那就需要改变物体前进选择时的概率,让游走的对象更有可能向这个方向前进或是更可能前进多少,也就是说我要让概率非均匀分布。一提到分布大家最熟悉的莫过于正态分布(即高斯分布),钟形曲线深入人心。我们可以借用高斯分布,决定在某一方向上的前进距离,书上给出了根据高斯分布确定位置绘制出的图:
在这里插入图片描述
不难看出,明显中轴部分,绘制过的圆形更多。

而当我们想要自定义一种概率分布时,也有不错的办法——蒙特卡洛算法。这里引入了资格概率的概念,利用两个随机数,一个作为产生概率,另一个作为判断概率能否使用的资格概率,从而可以按照一定的映射函数,生成这样的变化概率,书上给出的例子是按照y=x的映射实现的:

float montecarlo()
{
      
	while (true)
	{
      
	     float r1 = random(1);  
	     float probability = r1;    
	     float r2 = random(1);      
	     if (r2 < probability)
	     {
                   
	     	return r1;   
	     }  
	}
}

Perlin噪声

随机数生成器固然可以带来很多的创作想法,但是完全随机的随机数生成器不够符合自然界的规律,大开大合的变化总是让我们觉得非常不自然和唐突,这也成了我们引入Perlin噪声的一大原因。Perlin噪声能生成符合自然排序(“平滑”)的伪随机数序列,Processing的内置函数noise()就为我们提供了很好的Perlin噪声生成办法。

由于noise()函数可以是多维函数,所以我们可以通过传入不一样的值,来得到不一样的噪声值,一维噪声我们可以用于改变物体位置,而二维噪声则可以用于图像像素,进行亮度色彩的改变。而当需要完成屏幕上的映射时,我们可以使用Processing提供的map()函数。

动手实践——“野蛮生长”

(因为到后期运算量就上来了,所以时间就有点长,结果CSDN嫌太大了呜呜,弄gif导出都导了将近一小时了,我作业呜呜呜…)
在这里插入图片描述
其实这个小创作的灵感来自于随机游走这一章节最后,作者说利用噪声也可以模拟出树形生长的状态,我在这种想法上进行了拓展,可以看作自然界中,种群的增长爆发式增长,同样也可以把每个Walker看作生活中的我们,从一点发散出多点,可以描绘我们的人际关系。我利用了Perlin噪声控制每一次位置的变化,同时利用随机数改变每一帧描绘时的边缘色彩,话不多说,来让我们看看究竟是如何实现的。

首先参考了原始的随机游走模型,我们需要先准备一个Walker类。首先是类内的成员变量,我们需要一个列表来存储之前每一次walker走过的位置,这样子在重绘的时候才能调用继续绘制,我定义了一个PVector类的动态list,源于processing的ArrayList类;再有就是之后利用Perlin噪声时,令噪声函数发生变化的tx与ty,贴出所有之后我们会用到的变量:

PVector position;
ArrayList<PVector> history = new ArrayList<PVector>();
ArrayList<Walker> generateWalker = new ArrayList
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值