Open walnutpedia opened 8 years ago
下面代码里我用 colorMode() 将 sketch 的颜色模式设置为 HSB(HSL),然后在下面正态分布随机的时候把 S 和 B 设置高一点的值,这样随机出来的颜色会比较明亮小清新。
import java.util.Random;
Random generator;
void setup(){
size(400,400);
background(255);
colorMode(HSB, 360, 100, 100);
generator = new Random();
}
float getValue(float original, float mean, float sd){
return sd * original + mean;
}
void draw(){
//get x
float posX = (float) generator.nextGaussian();
posX = getValue(posX, width/2, width/6);
//get y
float posY = (float) generator.nextGaussian();
posY = getValue(posY, height/2, height/6);
//get color
float dotFillH = (float) generator.nextGaussian();
dotFillH = (int) getValue(dotFillH, 180, 90);
float dotFillS = (float) generator.nextGaussian();
dotFillS = (int) getValue(dotFillS, 70, 5);
float dotFillB = (float) generator.nextGaussian();
dotFillB = (int) getValue(dotFillB, 85, 2);
//get ellipse size
float dotSize = (float) generator.nextGaussian();
dotSize = getValue(dotSize, 30, 15);
noStroke();
fill(dotFillH, dotFillS, dotFillB, 70);
ellipse(posX, posY, dotSize, dotSize);
}
import gifAnimation.*;
float t = 0;
int h = 0;
GifMaker gifExport;
void setup(){
size(400,400);
colorMode(HSB, 360, 100, 100);
background(h,100,100);
gifExport = new GifMaker(this, "export.gif");
gifExport.setRepeat(0);
}
void draw(){
if(h==360){
h = -1;
}
h++;
background(h,72,82);
float n = noise(t);
float x = map(n,0,1,0,width);
ellipse(x, 180, 16, 16);
t += 0.01;
gifExport.setDelay(1);
gifExport.addFrame();
}
void mousePressed(){
gifExport.finish();
}
将背景设置为渐变的颜色。 使用 noise() 按照 t 递增生成的随机数决定小球的X坐标,来来回回的,好像迷了路踌躇不定。效果如下:
生成 gif 文件的方法见代码。gifAnimation 这个库得单独下载。
开始学Processing了,使用的资料是:
The Nature of Code 这本不算基础书籍,主要讲怎样用 Processing 来模拟真实世界的规律,涉及到利用(伪)随机数和概率来设计算法。因为这本没有 Processing 语法和API的讲解,可能不太适合没有任何编程经验的人来入门。
Processing.org tutorials 这个是 Processing 官方的教程了,Text Tutorials 那部分组织得挺好的,基础 API 和语法可以从这边来了解。
今天主要看的是 https://processing.org/tutorials/overview/ 这篇overview 和 http://natureofcode.com/book/introduction/ NoC的 Introduction章节。
Processing 概述与环境准备
其实 Porcessing 应该算是几个东西:
语言这边其实没什么特别要说的,基本是简化了的 Java。编译的时候会先转换成Java代码。其实不用 Processing 语言直接用 Java 与 Processing 的 API 来写也是可以的,而且可能更适合复杂一些的项目。初期先使用 Processing 语言来熟悉它提供的API 吧(这也是官方教程推荐的做法)。
关于 IDE, 懒得吐槽了…… 实在太差劲了。使用了之后马上抛弃,先安装 processing-java 命令行工具, 然后在 Atom 里安装 Processing 插件和语法高亮。除了没有实时错误提示,其他都OK。
Processing 项目
每个Processing项目叫做一个 sketch。 代码文件的后缀为 .pde 。
Processing 里比较基础的方法有:
size(), background(), stroke(), line() 之类的。 如果只用这些语句,那么生成的图像就是一个静态的图像。
如果提供了 void setup(){} 和 void draw(){} 的话,那就是一个 interactive program. setup 只执行一次,draw 会不断重复执行。 所以 setup 用来初始化环境(比如设定 sketch 的尺寸), draw 用来执行动画。 此外还有一些事件方法,比如 void mousePressed(){}, 每次点击鼠标就会执行。
另外每个 sketch 里还有一些全局变量, 比如 mouseX, mouseY 提供了鼠标在画布里的坐标;width 和 height 则是画布的宽高(不过这俩是 size() 执行设定尺寸之后才设定的)。
saveFrame() 方法可以将项目输出为图像。注意,如果这句放在 draw 里, 每次draw执行都会输出一张新的图片。
size(400, 400, P2D) 这句, P2D 的意思是用 OpenGL 来快速渲染2D图形。 P3D 是用 OpenGL 渲染3D。还可以是 PDF,后面接输出路径。
loadStrings() 和 loadImage() 这俩可以从sketch项目文件夹下的data文件夹(手动创建)里读取数据。
NoC Intro
随机数
利用随机数和概率可以构建出特定的算法,来实现某种目的。 Processing 提供了生成随机数的伪随机算法 random()。 如果想要让某种事件发生的可能性高于平均值,那就需要用某种方法来影响概率的分布。 比如可以建一个数组,里面某几项的值是重复的,然后用 random 来随机一个数组index,那么重复的项被随机到的几率就会大一些。 还可以生成0-1之间的一个随机浮点数 x ,然后判断 x 的范围,比如 x < 0.1 的概率就是 10% ,小与 0.4 的概率就是 40%。
正态分布
实际上自然界很多事情的概率分布是遵循正态分布的。比如一群猴子的身高…… 这里面涉及的主要概念是 平均值(Mean) 、标准差(Standard Deviation, SD, sigma) 。 可以使用Java 提供的 Random 类来自动处理正态分布相关的计算。
nextGaussian() 是根据 平均值0,标准差 1 来生成的。 下面的代码会让生成的数符合自己需要的正态分布:
Perlin Noise
Processing 提供了一个 noise(), 用来生成 Perlin Noise. 是变化很平滑的一个函数。传入一个值会生成0-1之间一个与之对应的唯一值。也就是说,传进去的参数会有一个对应的确定返回值。 noise() 可以传入1、2、3 个参数。 分别对应 一维、二维、三维。
这里需要理解的地方是,什么是二维噪音?一维 Perlin Noise 生成的某个数 x 有这样的规律: 它与它前一个值还有后一个值离得很近,具有相似性。 二维的 Perlin Noise 生成的某个数 x 则与它所有平面方向上相邻的值都相似。
一维的 Perlin Noise 值会有一种 「wandering」「晃来晃去」 的感觉。 二维的 Perlin Noise 值可以用来模拟云或者一些特定材质。
Perlin Noise 有很大的作用。它既不是颜色,也不是坐标,只是值。 可以用它生成的值来操作其他值的呈现,从而实现很多效果。非常好玩儿。
NoC Intro 总结
introduction 这章看起来为接下来的章节定下了基调。random 随机、正态分布随机、Perlin Noise 都是为了模拟现实世界的规律可以用到的工具。但这些不是万金油,还有更多的工具需要学习。学起来太好玩儿了。只是 Intro 章就这么大的信息量,后面的信息量估计也不会小…… OK,今天是学习的第二天,Intro 章学完了。
可能遇到的问题