🔥Blender傅里叶画画

Contra
2019-12-11
🔥Blender傅里叶画画

本篇效果:

fs-blender-3d-all-2


前言: 最近在【编程德鲁伊】的【傅里叶级数可视化】章节中,练习了傅里叶级数基础原理的可视化,演示了周期方波曲线,可以分解为一系列正弦波曲线:

fs-js-5

上边是JavaScript (React) 版,另有 Python (Blender) 版、 Unity 版。

这次拿学到的知识做个实验,试试喜闻乐见的【用傅里叶级数画画】,并尽可能简单直观的解释一下原理。


自认为简单直观的原理解释

之前练习的可视化,都是在二维空间进行,例如正弦波: py-sine

方波(通过傅里叶级数): fs-blender-short

图中左半边的圆周(Epicycle)和右半边正弦波/方波的关系:

  • 左半边是一个运动点,在一个圆周或多个圆周组合上随着时间t转动
  • 右半边,是将时间t映射到横轴x轴上,纵轴仍是运动点当前的y值保持不变。

也就是说,把时间域转换为空间域,就能从一个圆周得到正弦曲线,或者从一系列圆周组合,得到方波曲线

我们把方波可视化左右两边的运动点轨迹也画出来:

fs-blender-square

fs-blender-epicycle-square


左半边由一系列圆周(Epicycle)组成的轨迹,与右半边的方波(Square)轨迹,其实只是同一个运动点在不同空间里的展现方式而已。

豁然开朗有没有!!!(此处插入打赏掌声!)

为了说的更清楚一些,接下来把空间域从二维换到三维,时间t不再映射到x轴,而是映射到z轴上:

fs-blender-3d-sine-2

上图从正面看过去,仍是一个圆周,而在三维空间里旋转坐标轴,从侧面看过去时,它实际上就是一个正弦曲线。

方波的也一样: fs-blender-3d-square-1

正面的橙色轨迹,转换角度,从侧面看,就是方波的曲线。

再次豁然开朗有没有!!!


进一步,根据傅里叶级数原理,为了得到方波(橙色),就要想办法得到组成方波的一系列正弦波(金黄色): ![fs-blender-3d-items-1](./assets/fs-blender-3d-items-1.png)

换一个视角,为了得到最终的运动轨迹(橙色),就要想办法得到组成轨迹的一系列Epicycle圆周(金黄色):

fs-blender-3d-items-2


而这个橙色的运动轨迹,可以是各种形状,也就是说,无论想画什么图形,只要按照傅里叶级数的原理,找到一系列Epicycle圆周,就可以画出来了!

金猪报喜:

fs-blender-3d-pig

傅里叶本尊:

fs-blender-3d-fourier


怎么样,这样去理解傅里叶级数画画的原理,是不是容易了一些? 饿不饿,再给你煮碗面?


接下来要解决的,就是如何为“任意”图案找到对应的一组Epicycle圆周的问题。

从数学上讲,就是求傅里叶级数里每个子项对应的傅里叶系数(a和b):

各项系数a和b都找到后,合起来就可以得到f(x)。

求傅里叶系数的方法有很多,积分、傅里叶变换等。 详细的原理推导,我还没有复习重修,所以对于如何把大象装冰箱的回答,仍然是:

1.打开冰箱门;2.把大象装进去;3.关门。

直接对图案轨迹进行傅里叶变换,即可得到傅里叶系数。

而在计算机程序里,所有的数据都是离散的,所以实际上程序里用的是离散傅里叶变换。

关于这个环节,参考资源较多,尤其是用Web前端/JavaScript/p5.js做的不少,列在后面。

本文的配图和动画,是用 Blender + Python 完成:

blender-fs-draw

等等老乡,还没完。

从上图里傅里叶的配色就能看出,我其实原本是打算画 Miku 酱的(初音未来):

img_MIKU_us

然而码到用时方恨不会,关于傅里叶画画这个问题,其实更难的是找到合适的图案轨迹,并不是随便一个图都能轻松画出来的,这也是为什么上文中,我给任意图案的“任意”两字加了引号。

从数学上讲,在一些特定条件的约束下,一个函数才能用傅里叶级数来表达。 而找出这个图案轨迹的过程,复杂度远超用傅里叶级数画轨迹本身。 后面将附上其他高人的文章供参考。

本文投入的精力仅能画简单的轨迹线,所以Miku就换成了傅里叶他老人家🙂:

fourier

最终效果(三个视角):

fs-blender-3d-all-2



参考资源


Talk is cheap. Show me the code!

本例及【编程德鲁伊】系列大部分代码都开源在这里: https://github.com/avantcontra/coding-druid


公众号/B站/小红书/抖音/知乎:实验编程

实验编程社群资源、公开课: https://ghc.h5.xeknow.com/s/hzkMX

实验编程情报中心(会员): https://ghc.h5.xeknow.com/s/2BCFuJ

Cheers🍻

Contra