Processing模拟中`r=r=>(r-5)`语句的作用是什么?
解析推特简化Processing代码中
r=r=>(r-5)*(...)的作用 这段代码是推特上受字符限制压缩成单行的p5.js代码,展开后核心困惑点在于r=r=>(r-5)*(10 + w*(z = 1 - sin(t%120/240*PI)))这个表达式,下面拆解其作用:
完整代码展示
单行压缩版
t=0,draw=e=>{for(t++||createCanvas(w=400,w,WEBGL),background(w),fill(x=0),rotateX(d=t/120),rotateY(d),rotateZ(d);x<1331;)push(r=r=>(r-5)*(10+w*(o=1-sin(t%120/240*PI)))),translate(r(a=x%11),r(b=x%121/11|0),r(c=x++/121|0)),pop(box(10+o*(666==x?90:-10)))};//
展开易读版
t = 0; draw = e => { for( t++ || (createCanvas(w = windowWidth, w, WEBGL), background(w), fill(x = 0), rotateX(d = t/120), rotateY(d), rotateZ(d)); x < 1331; ) { push(r = r => (r - 5) * (10 + w * (z = 1 - sin(t%120/240*PI)))); translate( r(a = x % 11), r(b = (x % 121)/11 | 0), r(c = x++/121 | 0) ); pop(box(10 + z*(666 == x ? 90 : -10))); } };
核心表达式拆解
r=r=>(r-5)*(10 + w*(z = 1 - sin(t%120/240*PI)))是变量赋值+箭头函数定义的组合,本质是在循环里动态生成坐标转换函数:
- 箭头函数
r=> (r-5)*...的作用:- 输入参数
r是拆分出的网格坐标分量:a=x%11、b=(x%121)/11|0、c=x++/121|0,这三个值的范围都是0~10(因为1331是11³,对应11x11x11的立方体网格)。 r-5:把坐标从0~10偏移为-5~5,将整个网格的原点移到中心位置。*(10 + w*(z=...)):生成随时间变化的缩放因子——z=1-sin(t%120/240*PI)计算出周期为120帧的动画值,z范围是0~2,最终缩放因子在10到10 + 2w之间波动,实现网格整体的呼吸缩放动画,且缩放幅度和画布宽度w挂钩。
- 输入参数
- 写在
push()参数里的原因:
这是推特字符压缩的技巧——利用逗号运算符和函数调用的参数位执行赋值语句,push()本身仍承担矩阵入栈(保存当前坐标系状态)的作用,它的参数会被忽略,真正目的是在这个位置完成r函数和z变量的定义。
补充:push/pop的特殊写法
原代码里pop(box(...))是压缩时的投机写法:JavaScript中函数调用的参数会先执行,所以会先绘制box(),再把box()的返回值传给pop(),但pop()本身不需要参数,实际效果等价于先画立方体,再执行pop()恢复坐标系状态,和标准的push() -> 绘制 -> pop()流程一致。
内容的提问来源于stack exchange,提问作者Antoni Parellada
相关产品推荐
相关产品推荐

