- 前几天叶师傅在朋友圈里发了个小代码,点进去一看gif感觉不咋地,就没当回事,今天看书的时候想起来了这个代码遂找来研究(原文—— http://mp.weixin.qq.com/s/VFFzcIdJdYKQHfz4oWKINA ),打了三遍,第一遍不动,第二遍疯动,第三遍才打成功,也许是被催眠了吧,图出来后效果是惊到了我的,
从此以后再也不相信gif版的processing图了!
废话不多说了,上分析:
首先是前两次打错的例子,1和i虽然在键盘上相距很远,但人(或者说只有我一个?)主观上会搞混淆,
然后就是括号了,不过我这个错误应该多发于抄袭的时候,哎,人笨就连抄袭也抄不好,说明那些抄袭大师也是有异于常人的能力的,最起码人家细心啊~
错误例子:
void setup(){
size(800,800);
smooth();
}
void draw(){
background(255);
noFill();
stroke(0);
for (int i = 0;1<20;i=i+1){
//上一行的i错写成了1
//用毫秒数和简单运算做个错位,除以6.18来调节一下快慢,角度转弧度
float degree = radians((millis()+50*i)/6.18);
//弧度用在正弦波里
float pingPong = sin(degree);
//正弦波mapping到笔触粗细上
float sw = map(pingPong,-1,1,50,10);
strokeWeight(sw);
//正弦波mapping到圆圈大小上
float r = i*map(pingPong,-1,1,160,60);
ellipse(width/2,height/2,r,r);
}
}
void setup(){
size(800,800);
smooth();
}
void draw(){
background(255);
noFill();
stroke(0);
for (int i = 0;i < 20;i=i+1){
//用毫秒数和i简单运算做个错位,除以6.18来调节一下快慢,角度转弧度
float degree = radians(millis()+(50*i)/6.18);
//上一行(50*i)中左括号不要
//弧度用在正弦波里
float pingPong = sin(degree);
//正弦波mapping到笔触粗细上
float sw = map(pingPong,-1,1,50,10);
strokeWeight(sw);
//正弦波mapping到圆圈大小上
float r =i*map(pingPong,-1,1,160,60);
ellipse(width/2,height/2,r,r);
}
}
分析:
下面进入正文
首先观察(构思)目标,像素描临摹一样先观察,在解析,想象结构,
从成品图中可以看出几个现象:
1,有很多圆,圆心相同,同心圆;
2,圆会随时间运动;
3,圆的运动方式为扩大后缩小,
一个扩大与缩小为一个循环的规律运动;
4,扩张的速度随时间变慢,随后缩小时的速度又随时间变快;
5,圆有描边;
6,圆的描边也会运动,随着圆扩大而变粗,
随着圆的缩小而变细;
然后根据现象,像推导定理一样猜想/推导一下达成这些效果/目标所要使用的一些手段/方法/工具:
1,根据现象2得出该程序为动态图像,所以需要用到draw函数
又可得出时间数可能与运动相关;
2,根据现象3和6的规律性运动可以得出该程序运动可能具有周期性,
进一步得出可能需要用到正弦函数;
3,根据现象5可以得出该程序需要用到stroke函数;
4,根据现象6可以得出该程序需要用到strokeWeight函数;
接下来开始对代码进行分析,我一直认为写代码和魔法很像,我还一直认为魔法应该是有人像创建操作系统一样,
创建一套能够调动各种力量的协议啊(就是类似的专业术语)什么的,然后再创建一套能够对这些能量进行操控的方法,
比如编程语言这种,然后随身要带魔能源,比如魔法石什么的。(有时候一些特别的“操作系统”与大环境不兼容,这时候就需要带上写满操作协议的魔法书了,比如一个死灵法师要调用亡灵法术,而周围都是元素和奥术协议的环境时)
举个例子,要造一个火球,就是通过某种用于魔法的语言编写/下达指令,比如:
//让你释放魔法的地方
创建魔能协议空间;
//手掌那么大,默认单位为厘米
尺寸(10x10x10);
//能量平滑不刺手
和谐();
//能量调用类型有两种,奥术和元素,将x单位魔能转换为火元素赋值给能量A
元素 A=火(x);
//如果要让火球打击更远的目标,就需要加一个力量函数来给球体一个加速度
//力量函数需要用到奥术类型的能量,直接用魔能无需转换
奥术 B=y;
//设置力量的函数为:力量(能量,x坐标,y坐标,z坐标),一般情况下给出力量参数就可以自行瞄准近距离目标
//也可以不用力量函数自己把火球甩出去
力量(B)
//形成球体,r为球体半径,不能超出力场空间,A为塑造球体的素材
球体(r,A);
//下达运行命令后火球就开始聚集了
运行;
不说废话了,下面是一个码盲经过没几天的学习进行的肤浅分析:
void setup(){
size(800,800);
smooth();
}
void draw()
{
background(255);
noFill();
stroke(0);
//事先给电脑说好有这么个数“i”,i是什么类型的数,i的范围怎么样,i如何变动
for (int i = 0;i < 20;i=i+1){
//如果想要使一个数周期性变动,就需要用到正弦函数,又因为正弦函数是弧度制,
//所以必须要将直观的角度变成不直观但是能嵌入进正弦函数的弧度
//(millis()+50*i)/6.18)将时间与i进行关联,
//用毫秒数和i简单运算做个错位,除以6.18来调节一下快慢,
//得出的数字从角度转到弧度(除以6.18大概是因为黄金律?)
float degree = radians((millis()+50*i)/6.18);
//把上一步得到的名为degree的数嵌进正弦函数里,让它开始周期性运动,开始转圈圈
float pingPong = sin(degree);
//设描边粗细为sw,开始给sw数值,sw=pingpong,但pingpong在正弦函数里,
//正弦函数值域为(-1,1),太小,所以我们要变动一下,变大了才能在
//直观视觉上看出变化,这种变动要用到map,也就是“映射”,
//把值域(-1,1)变动成(50,10),然后慢慢取pingpong在其中映射出来的值
float sw = map(pingPong,-1,1,50,10);
//将sw应用到描边粗细中
strokeWeight(sw);
//设圆的半径为r,将pingpong进行映射,取值,pingpong*i是为了让圆的半径
//在周期变动的基础上进一步与i发生联系
float r =i*map(pingPong,-1,1,160,60);
//开始画圆,圆心为画布宽的一半,长的一半,长半径与短半径相等,为正圆
ellipse(width/2,height/2,r,r);
}
}
这段代码里用到了这样几个函数/知识点:
正弦函数制造周期;
角度转弧度以适应正弦函数;
映射,用映射将小数字变成大数字;
犹豫不决就用黄金分割率;
接下来在理解的基础上进行进一步魔改:
1,加上颜色;
2,颜色扩张时变绿,缩小时变红;
根据要求可以得出:
1,要用到stroke(r,g)函数;
2,r,g数值要与pingpong关联
3,r(0,255)
g(0,255)需要映射
4,纯红(255,0) 0
g开始增长,至225
纯黄(255,255) pi/2
r开始减少,至0
纯绿(0,255) pi
r开始增长,至225
纯黄(255,255) 3pi/2
g开始减少
纯红(255,0) 2pi
此为一个周期
也就是说这个过程也是一个正弦曲线的过程
sin(x)中
x=0 ,pi/2,pi ,3pi/2,2pi
r=255,255 ,0 ,255 ,255
g=0 ,255 ,255,255 ,0
将(-1,1)映射为(0,255)
……操,不会算了
那就直接r=random(0,255)
g=random(0,255)
b=random(0,255)
吧!
第一次发帖,排版不怎么会,关于这段代码,我还有很多问题,最大的问题是,如何才能将自己的想法精确的或者准确地用代码实现,这个思维方式,过程,我认为比代码本身更加重要。
分析写得很幼稚,有问题还希望大家指出来,如果能让和我一样的新人看懂了,我也很高兴,因为把别人讲懂了说明我也懂了一点点
- 本文固定链接: http://iprocessing.cn/2017/09/25/文盲角度代码分析《催眠(作者:叶师傅)》/
- 转载请注明: DurianBomb 于 Processing编程艺术 发表
《文盲角度代码分析《催眠(作者:叶师傅)》》有 2 条评论