欢迎光临
我们一直在努力

用4000个散点画一只“赛博水母”:MWORKS..Syslab参数方程可视化实践

如果只看最终效果,很难想到一只不断收缩、摆动,甚至有点像在水中游动的“水母”,其实只是由 4000 个散点组成的。

最近在 MoHub 上看到一个挺有意思的科学可视化案例:把一个 Python“数字生命”脚本移植到了 MWORKS Syslab,使用 Julia 和内置 TyPlot 绘图库,通过参数方程实时计算几千个散点的位置,最终生成一只动态的“赛博水母”。

我把 cyber_jellyfish.jl 实际跑了一遍,又导出了几个关键帧。相比最终动画,我更感兴趣的是:几行数学公式,到底是怎么慢慢长成一只水母的?

一、它其实不是“画”出来的

这个案例并没有水母的三维模型,也没有预先准备好的轮廓图片。

画面里的每一个亮点,都对应一个通过数学公式计算出来的二维坐标。

整个脚本可以简单理解成三步:

生成 4000 个粒子 → 根据参数方程计算坐标 → 随时间不断重新计算并绘制。

因此,这只水母并没有固定形状。

当时间参数 t 发生变化时,4000 个点的位置也随之变化,连续播放以后,就形成了类似伞盖收缩、触须摆动的动态效果。

这类图形比较有意思的地方就在这里:最终看到的是一个复杂形态,但背后真正控制它的只是少量数学规则。

二、4000个点是怎么变成“水母”的?

脚本首先给每个粒子生成一组基础参数:

x = mod.(i_data, 200)
y = i_data ./ 43.0

k = 5.0 .* cos.(x ./ 14.0) .* cos.(y ./ 30.0)
e = y ./ 8.0 .- 13.0
d = (k .^ 2 .+ e .^ 2) ./ 59.0 .+ 4.0
a = atan.(k, e)

这些量在整个动画过程中基本不变,可以理解成每个粒子的“初始属性”。

真正让水母动起来的是后面的时间参数 t。

每一帧都会重新计算类似下面的表达式:

q = 60 – 3*sin(a*e) + k*(3 + 4/d*sin(d^2 – 2*t))
c = d/2 + e/99 – t/18

然后再把 q 和 c 转换成最终的二维坐标:

X = q*sin(c) + 200
Y = (q + 9*d)*cos(c) + 200

这里的 q 可以大致理解成粒子离中心有多远,c 则影响粒子的分布方向。

真正产生动态效果的关键,是公式中的:

d² − 2t

以及:

−t/18

随着 t 不断增加,粒子的半径和角度都在缓慢变化。

于是原本静态的一团散点就出现了连续变形。

三、实际跑出来是什么效果?

在 Syslab 中运行 cyber_jellyfish.jl 后,会出现一个黑色背景的绘图窗口。

整个画面被分成两个区域。

左侧显示核心数学公式,右侧则是由 4000 个散点组成的水母。

图1:完整运行界面

比较有意思的是,左右两边实际上使用了两个独立坐标区。

左侧公式基本保持不动,右侧水母则随着每一帧不断刷新。这样既能看到动画,也可以同时观察它背后的数学表达式。

单独截取其中一帧,可以比较明显地看到水母的结构。

图2:水母形态

上方的散点聚集成类似伞盖的形状,下方则自然拉出大量细长分支。

这里并没有专门写“生成伞盖”或者“生成触须”的程序,最终结构实际上都是参数方程共同作用产生的。

换一个时间点,形状又会发生变化。

03:水母形态演化

可以看到伞盖的展开程度和下方点云分布已经明显不同。

如果把这些帧连续播放,变化会更加直观。

图4:赛博水母循环

这时候看起来就不再像一张数学图,而更像某种不断呼吸和游动的“数字生物”。

四、为什么散点看起来会有发光感?

如果 4000 个点全部使用同一种颜色,最终效果其实会比较平。

脚本还根据粒子的 depth 和 shimmer 等参数调整显示效果,使散点呈现出不同的亮度和色彩层次。

因此最终看到的并不是一团纯白色散点,而是带有青蓝、白色以及淡紫变化的点云。

深浅不同的粒子叠在一起之后,会产生一定的空间层次,看起来就有了类似半透明水母的“发光感”。

这也说明科学可视化里一个很容易被忽略的问题:

坐标决定形状,而颜色、大小和透明度决定我们最终如何感知这个形状。

同样一组数据,换一种视觉映射,最终效果可能完全不同。

五、4000个点×480帧,代码怎么避免重复计算?

动画一共需要计算 480 帧,每帧又有 4000 个粒子。

如果每次都重新创建数组、重复计算不随时间变化的变量,虽然数学逻辑没变,但会增加很多不必要的开销。

这个脚本做了两个比较典型的 Julia 优化。

第一,把 k、e、d、a 等与时间无关的参数提前算好,动画循环里只计算真正和 t 有关的部分。

第二,提前申请存放坐标的数组:

x_data = Vector{Float64}(undef, N)
y_data = Vector{Float64}(undef, N)

然后使用 compute_frame! 直接更新数组内容,而不是每一帧重新创建一组新数组。

这种带 ! 的函数命名在 Julia 中很常见,通常意味着函数会直接修改传入的数据。

对于单次计算来说,这种差异可能并不明显;但放到“4000 个点 × 数百帧”的循环里,减少重复内存分配就更有意义。

所以这个案例除了画图,本身也是一个比较直观的 Julia 数值循环练习。

六、它算不算真正的“数字生命”?

从视觉效果看,这只水母确实有一些“活物”的感觉。

但从模型本身来说,它仍然是一套艺术化的参数方程可视化。

水母的运动不是流体计算出来的,也没有建立柔性结构、浮力、阻力或者触须动力学模型。

所有形态变化,本质上都来自:

时间参数 t 改变 → 参数方程改变 → 4000 个散点重新排列。

因此不能拿它研究真实水母的游动机理。

但如果把它作为参数方程、Julia 图形编程和科学可视化的练习,反而很合适。

例如可以继续尝试修改粒子数量、公式参数、颜色映射和时间步长,观察最终形态如何变化;也可以保留这套绘制框架,换成其他参数方程,生成新的动态图形。

七、总结

这个案例最有意思的地方,不是“用 Syslab 画了一只水母”,而是它很直观地展示了:

数学公式可以直接决定一个图形如何生长、变形和运动。

4000 个点本身没有任何特殊之处,但经过参数方程组织以后,就形成了伞盖和触须;再加入时间变量,静态点云又变成了连续动画。

同时,脚本还涉及 TyPlot 散点绘制、双坐标区、逐帧刷新,以及 Julia 中的预计算、数组预分配和原地更新。

如果正在学习 Julia 科学计算,又觉得普通的函数曲线和散点图有点单调,这种案例倒是一个比较有趣的练习方向。

本文使用的赛博水母案例可在 MoHub 查看:

https://mohub.net/model/26011/summary

赞(0)
未经允许不得转载:171主机测评 » 用4000个散点画一只“赛博水母”:MWORKS..Syslab参数方程可视化实践
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址