首页 > 未分类 > 文盲角度代码分析《催眠(作者:叶师傅)》
2017
09-25

文盲角度代码分析《催眠(作者:叶师傅)》

  • 前几天叶师傅在朋友圈里发了个小代码,点进去一看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)

    吧!

 

 

第一次发帖,排版不怎么会,关于这段代码,我还有很多问题,最大的问题是,如何才能将自己的想法精确的或者准确地用代码实现,这个思维方式,过程,我认为比代码本身更加重要。

分析写得很幼稚,有问题还希望大家指出来,如果能让和我一样的新人看懂了,我也很高兴,因为把别人讲懂了说明我也懂了一点点



最后编辑:
作者:DurianBomb
这个作者貌似有点懒,什么都没有留下。

文盲角度代码分析《催眠(作者:叶师傅)》》有 2 条评论

  1. constrain constrain 说:

    的确好玩啊…
    这样子改了下

    int bb=128;
    void setup() {size(800, 800);smooth();}
    void draw() {background(bb);noFill();
    for (int i = 0; i < 12; i=i+1) {
    float degree = radians((millis()+50*i)/PI);
    float pingPong = sin(degree);
    float sw = map(pingPong, -1, 1, 50, 10);
    color cc=color(map(pingPong, -1, 1, 128, 240),map(pingPong, -1, 1, 10, 210),255-map(pingPong, -1, 1, 10, 210));
    stroke(cc);strokeWeight(sw);
    float r = i*map(pingPong, -1, 1, 160, 60);
    bb=ceil(255-brightness(cc));
    ellipse(width/2, height/2, r, r);
    }
    }

留下一个回复

你的email不会被公开。