一些有意思的 The Coding Train 编码挑战
警告:多图杀猫
背景
随着小朋友日夜长大,好奇心也不断增长。我作为家长自然希望能稍加引导,以免他长成个熊孩子。于是就去油管上找了下有啥面向初学者的编程课程,结果很有缘分地找到了一个叫The Coding Train
[1]的频道。主播名叫Daniel Shiffman
,订阅粉丝超百万。为什么说有缘分呢,因为Dan之前写过本书叫"The Nature of Code"
,国内也引进过,译作《代码本色》,并且在我的书架上积灰了多年:
书中使用Processing
模拟了一些自然系统。Processing
基于Java,包含了自己的IDE。而在油管频道中Dan则是大量使用了p5.js
。p5.js
继承了大部分的Processing
的API,并且可以直接在浏览器里运行,对于初学者来说会更友好。
频道的官网上有一块叫Coding Challenges
[2],是由频道粉丝提出一些小的idea,然后由Dan在直播中尝试用p5.js
或Processing
来实现,同时解释一些基础的编程知识。虽然中途时不时会翻车,但最终的实现效果通常都很不错。比如这个SuperShape3D[3]:
我家小朋友小时候就挺喜欢玩:
又比如这个Phyllotaxis[4]:
可以看出Dan真的很喜欢彩虹色。
不过有些东西就比较抽象,可能我比较喜欢,但小朋友就没啥兴趣。比如这个Kaleidoscope Snowflake[5]:
为了找到能让小朋友满意的玩意儿,我利用业余时间把频道里的这一块视频都撸了一遍[6],前后断断续续花了将近一年的时间。要不是因为疫情隔离原因Dan停更了一段时间,以及现在Dan好像又在写The Nature of Code 2
的样子,导致后期这部分视频数量急剧减少,不然可能会花上更多的时间。
遗憾的是,撸完了现有的视频也没找到更多能让小朋友满意的东西。不过有些东西让我觉得挺有意思的,就在这里记录下。
10PRINT
提问:生成下图需要多少代码?
答案是一行C64 Basic代码[7]:
10 PRINT CHR$(205.5+RND(1)); : GOTO 10
当然用p5.js
实现的话不只一行[8]。信息时代早期人们的创造力着实让我着迷。
Perlin噪声
似乎IT行业中,除了游戏行业就很少会用到Perlin噪声。而在游戏行业里,最常用到Perlin噪声的地方就是程序化生成地形[9]:
大名鼎鼎的Minecraft
在生成地形时就大量使用了Perlin噪声[10]。此外Dan还展示了如何用多维的Perlin噪声实现那些看似随机,实则无限循环的动图[11]。
给图标磨个圆角
据说某米今年花了200万给自家的图标磨了个圆角[12],甚至还给了个公式,让人不明觉厉。然而早在5年前的2016年[13],Dan就已经手撸过同一个公式了[14]:
Dan作为纽约大学艺术学院的副教授,不知道在设计界有多大的名气?“东瀛罗永浩”的设计团队会是在Dan这里得到的灵感吗?
傅立叶变换
这是我个人比较喜欢的一个主题。首先,一系列大小不同的相切圆环的运动轨迹居然可以形成某种分形[15]:
然后如果都在同一个方向上叠加的话就可以重现傅立叶变换[16]:
依稀记得当年学数字信号处理的时候,老师让我们自己手绘不同周期的正弦波并叠加,以此来直观感受对方波的傅立叶变换。而现在的小朋友就可以很方便地在浏览器里手撸一个出来。我看着他们,满怀羡慕。
上面是一维的情况,简单扩展到二维的话可以画出一些美妙的图形[17]:
而对任意的平面点坐标序列做傅立叶变换的话,就可以绘制任意图形[18]:
3D
p5.js
不但可以绘制2D图形,绘制简单的3D图形也很方便[19]:
不过毕竟只是个lib,连个场景图都没有,做略微复杂点的场景就很痛苦[20]:
Dan在做这个魔方的时候也是屡屡翻车。
Pi Collisions
这个我个人也非常喜欢。谁能想到两个滑块之间的完全弹性碰撞次数居然跟π
有联系[21]:
著名的3b1b对此也有解释[22]。另一篇解释[23]中还牵涉到了量子计算,其中提到了把大滑块看成了相同质量的小滑块的组合,而这正是Dan在实现时用到的方法!
Ray casting
最近某来步了特斯拉自动驾驶“杀人”的后尘引起热议[24]。跟特斯拉一样,某来也没有激光雷达。Musk很早就说过傻瓜才用激光雷达[25]。那么如果有完美的激光雷达会怎样?借助Dan的小项目告诉你[26]:
如果在发出的每条射线的方向上都可以精确得知自己到障碍物的距离,那么就可以渲染出一个伪3D的场景[27]了:
早期的FPS游戏如Wolf3D和Doom等都用了这样的方法。相比纯视觉的方案,实现简单可靠,还有完美的可解释性,确实是连傻瓜都会用的方法。
MetaBalls
这本来是个平平无奇的小项目[28],然而我的实现却跟Dan的实现在运行效率上差了不只一点半点。仔细比对以后发现差异就在一个destructure操作上:
const [dx, dy] = [x - bx, y - by];
这个操作是在双重循环里的,改成单独赋值的话效率明显提升:
const dx = x - bx
const dy = y - by
尝试做了一下benchmark,发现在Firefox里destructure操作有明显的性能问题[29]:
Chrome里结果更接近一些,但destructure操作的性能还是不如直接赋值。所以说即便浏览器普遍都原生支持了ES6语法,使用一个ES5的transpiler还是很必要的。
先就这样吧,如果Dan以后又更新了哪些有意思的东西我再来更新一波。
参考资料
- [1] The Coding Train
- [2] Coding Challenges · The Coding Train
- [3] 3D Supershapes - Coding Challenge #26 · The Coding Train
- [4] Phyllotaxis - Coding Challenge #30 · The Coding Train
- [5] Kaleidoscope Snowflake #SupportP5 - Coding Challenge #155 · The Coding Train
- [6] TheCodingTrain Coding Challenges
- [7] 10 PRINT CHR$(205.5+RND(1)); : GOTO 10
- [8] 10PRINT in p5.js - Coding Challenge #76 · The Coding Train
- [9] 3D Terrain Generation with Perlin Noise in Processing - Coding Challenge #11 · The Coding Train
- [10] Noise generator – Official Minecraft Wiki
- [11] Perlin Noise GIF Loops - Coding Challenge #136.2 · The Coding Train
- [12] 价值200万的小米新LOGO 你上你也行?
- [13] Coding Challenge #19: Superellipse
- [14] Superellipse - Coding Challenge #19 · The Coding Train
- [15] Fractal Spirograph - Coding Challenge #61 · The Coding Train
- [16] Fourier Series - Coding Challenge #125 · The Coding Train
- [17] Lissajous Curve Table - Coding Challenge #116 · The Coding Train
- [18] Drawing with Fourier Transform and Epicycles - Coding Challenge #130.1 · The Coding Train
- [19] Cube Wave by Bees and Bombs - Coding Challenge #86 · The Coding Train
- [20] Rubik’s Cube Part 3 - Coding Challenge #142.3 · The Coding Train
- [21] Calculating Digits of Pi with Collisions - Coding Challenge #139 · The Coding Train
- [22] Why do colliding blocks compute pi?
- [23] 这一切要从碰撞的滑块和量子搜索讲起。。。
- [24] 蔚来车祸之殇 乃新势力造车全行业之痛 _ 东方财富网
- [25] 特斯拉全自动驾驶硬件发布!马斯克明年推RoboTaxi:傻瓜才用激光雷达
- [26] Ray Casting 2D - Coding Challenge #145 · The Coding Train
- [27] Rendering Ray Casting - Coding Challenge #146 · The Coding Train
- [28] Metaballs - Coding Challenge #28 · The Coding Train
- [29] Benchmark: Destructure vs Assignments - MeasureThat.net