
这是兜兜鱼本次要带来的助力内容——代码检查。
身为一个进阶的创意编程学习者, 深深地感受过入坑阶段 想法不断涌现又无力创作的痛感,所以决定开设这个检查。来助力想入创意编程坑的任何人,具体分析相关的创意编程作品的代码意义。让大家理解的同时借鉴到灵感。希望能真正助力入坑人将想法通过代码表达,并且应用到创作中。

柔软质感的球体
今天到解析的作品来自openprocessing(http://www.openprocessing.org,一个processing爱好者网站,如果你目前还不知道,那么恭喜你找到群体了。)作品具体来自哪位大神本人已忘记..(。•ˇ‸ˇ•。)… ,某天狂网站时看到觉得非常有质感,就copy了代码。由于op上作品繁多,想要找回作者已有些困难。(如果知道,务必告知(o゜▽゜)o)
进入正题,先贴上源码。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18int time = 0; void setup(){ size(600, 600); } void draw(){ background(242); for(int i = 0; i < 360; i+=5){ float x = cos(radians(i)) * 50 + width / 2; float y = sin(radians(i)) *100 + height / 2; float w = sin(radians(time+i )) * 200; w = abs(w); float col=map(i,0,360,120,255); noStroke(); fill(col,0,88); ellipse(x, y, w, w); } time++; }
拆解注释:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29int time = 0; //设定了一个用来记录时间的变量 void setup(){ size(600, 600); //设定了窗口大小 } void draw(){ background(242); //设定了背景颜色 for(int i = 0; i < 360; i+=5){ //设定了一个i在0到360度之内以5°幅度增加的循环 //radians()把角度的数据转化成弧度的数据(由于processing的三角函数默认需要投入弧度制的角度) float x = cos(radians(i)) * 50 + width / 2; float y = sin(radians(i)) *100 + height / 2; //可以看到x和y是下方ellipse的位置坐标,利用三角函数计算出了每个圆心的位置 //并且把圆心移动到了画面中心 float w = sin(radians(time+i )) * 200; //【关键步骤】圆大小根据三角函数变换,time错开了每个圆的变化周期 w = abs(w); //取绝对值 //这个w是圆的大小,同样是利用三角函数计算,由于三角函数会取到负数,所以做了绝对值处理。 float col=map(i,0,360,120,255); //颜色根据i在0°和360°的变化改变自身数值 noStroke(); fill(col,0,88); //采用RGB色彩模式,col改变R通道的填入数值 ellipse(x, y, w, w); //画圆 } time++; //【关键步骤】 }
没错,processing就是辣么强大。短短19行简短代码就勾勒出了这个优雅柔软的球体,妙啊。
虽然已经贴上了重点注释,但是浓缩的精华需要慢慢地品尝,为了让大家能根源性理解,我就来分步深层地解剖一下内部原理。 这也就是“代码检查”的意义。
主要解释的问题有
1.三角函数的使用
2.【关键步骤】的“真相”
首先来解释三角函数的使用问题,在这个例子中用到三角函数的有变量有圆的x,y,w
即是圆的坐标位置以及大小。
例子中是去掉了圆的线条,只给它留下了填充色。有填充色的圆圈叠加在一起不断变换让我们在唯度及质感上产生了错觉。
这里可以使用到一个简便的技巧来查看“球体”的原型是如何的。
让我们去掉填充色,开启“球体”的线条

现在,球形毕露,“球体”是由N个圆不断重叠及变换组成的。
乍一看所有的圆都像是在做逆时针运动。但如果仔细观察圆的位置代码
你会发现:
1
2
3
4
5for(int i = 0; i < 360; i+=5){ float x = cos(radians(i)) * 50 + width / 2; float y = sin(radians(i)) *100 + height/ 2; }
x,y的值随着设定的循环条件 i<360而进行循环计算。
i的初始值为0,且以每次5的幅度进行增长,早晚要大于360。而且x,y值在后面没有任何的变化,所以哪里来的位置不断运动呢(⊙o⊙)…
刚刚也有提到圆的大小w也是使用三角函数计算的,而且圆的大小和不断变化的time有关
float w = sin(radians(time+i )) * 200;
因此,极有可能是圆的大小变化导致了我们的视觉错差。有个方法可以用来验证一下它。
与上个检测原型的方法类似,去掉无关因素,保留相关因素。
这一段我们要去掉圆大小(w)的变化,而保留圆的位置(x,y),就像这样
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20int time = 0; void setup(){ size(600, 600); } void draw(){ background(242); for(int i = 0; i < 360; i+=5){ float x = cos(radians(i)) * 50 + width / 2; float y = sin(radians(i)) *100 + height / 2; float col=map(i,0,360,120,255); noStroke(); fill(col,0,88); noFill(); stroke(0); strokeWeight(5); point(x,y); //画出每个圆心 } time++; }

现在我们得到的是一个椭圆形(由于计算y值的半径比计算x值半径大)的用点描绘的轨迹,是一张静态图像,这说明,我们的软球动态效果,都是基于椭圆的半径w的变化而变化的,与椭圆的位置x,y并无关系。
这一点确定以后,再把圆的半径添加回来。

你可能仍然感到疑惑,圆的半径明明是由三角函数数sin计算而来
1
2
3float w = sin(radians(time+i )) * 200; w = abs(w);

按道理w应该是根据sin的波动幅度变大由变小才对,为什么会给人一种移动的层叠交错效果呢,重点是投入sin中的参数有两个参数同时在变化,time和i。
time是逐渐递增的,其实可以看做是w在sin函数行进的横坐标。
如果我们只留下time就会发现:
1
2
3float w = sin(radians(time)) * 200; w = abs(w);

椭圆形的轨迹上每一点都是一个圆心,所有圆的半径在随着函数的计算做周期性的运动,为了让大家确定这是多个圆变化运动而形成的图形,我把其中一个圆圈标红。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25int time = 0; void setup() { size(600, 600); } void draw() { background(242); for (int i = 0; i < 360; i+=5) { float x = cos(radians(i)) * 50 + width / 2; float y = sin(radians(i)) *100 + height / 2; float w = sin(radians(time)) * 200; w = abs(w); float col=map(i, 0, 360, 120, 255); noFill(); if(i==0){ //角度为0的轨迹点标红 stroke(255,0,0); } else{ stroke(0); } ellipse(x, y, w, w); } time++; }
得到:

没错。这个图形就可以看成是以椭圆为轨迹形成的圆心在各自的位置伸缩自己的半径而形成的图形。
1
2
3
4
5
6
7
8for (int i = 0; i < 360; i+=5) { float x = cos(radians(i)) * 50 + width / 2; float y = sin(radians(i)) *100 + height / 2; float w = sin(radians(time+i)) * 200; w = abs(w); ellipse(x, y, w, w); } time++;
而让整个图形看起来像不断运动的球体的因素是加载在time后面的i,也是整个例子的画龙点睛之笔。
如果观察i的变化,会发现每次time增加的 i 的值都在不断变大。而time自身的增加是在循环外的,这意味着每个圆在计算各自半径的时候得到的time值都是一样的,而得到的 i 值确是后一个圆要比前一个圆大。 这就会导致他们用三角函数计算各自的半径w时会处在不同的位置,而取到不同的值。

取到不同的值就意味着前后圆的大小在随着函数的波动而先后波动。就像多米诺骨牌,每个圆的圆心是不变的,但它们的半径在有顺序的依次变大,又变小。因此会产生球体的视觉效果。
为了看得清楚,仍然保持刚刚标记的圆,以及标记每个圆的圆心位置。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33int time = 0; void setup() { size(600, 600); } void draw() { background(242); for (int i = 0; i < 360; i+=5) { float x = cos(radians(i)) * 50 + width / 2; float y = sin(radians(i)) *100 + height / 2; float w = sin(radians(time+i)) * 200; //i的变化错开了每个圆的周期变化。让它们依次变换。 w = abs(w); float col=map(i, 0, 360, 120, 255); stroke(#058CFF); strokeWeight(3); point(x,y); //标记圆心 if(i==0){ //挑出一个圆来标记 strokeWeight(3); stroke(#FF0505); fill(#058CFF); } else{ strokeWeight(1); fill(#FF0505); stroke(0); noFill(); } ellipse(x, y, w, w); } time++; }
可以看到标记的圆的位置未发生任何变化,而半径在前后有序地周期性变化。
一个圆是如此,所有的圆都是如此。
最后,锦上添花的一步是
1
2float col=map(i,0,360,120,255);//映射角度到颜色值 fill(col,0,88);
让圆的颜色的红色通道随着角度的变化而变深,增加立体感和美观度,去掉线条,填入颜色。几个柔软质感的球体就出现了。yes.
这就是本次的代码检查,希望对你有所帮助。
如果有任何问题。或者你有欣赏的作品但却不到一个合理的解释,欢迎私信我。或者提供你的作品源码,也许我会选择其一来做下一次的代码检查。
最后
以上就是炙热花卷最近收集整理的关于processing创意图形代码_代码检查|processing——柔软质感的球体的全部内容,更多相关processing创意图形代码_代码检查|processing——柔软质感内容请搜索靠谱客的其他文章。
发表评论 取消回复