曲线球
曲线球是我为Neverball开发的曲线生成工具。您可以在网络上使用曲线球!源代码可以在Github上获取,您可以在那边找到更多截图。如果您想将曲线球作为桌面应用程序运行,可以从Github下载发布版本或自己编译。别担心,编译曲线球很简单,尤其是如果您已经安装了Rust。哦,这个东西是用Rust语言编写的🦀。这意味着它一定很好,对吧?曲线疯狂 为什么选择曲线球?我正在为一个名为Neverball的开源游戏制作一组关卡,我需要一些炫酷的形状。Neverball已经有一个名为curve.c的曲线生成工具。它足以满足所有现有的Neverball关卡集(除了Nevermania—— fwp可能写了几个自己的脚本)。但curve.c只生成一种曲线:圆弧。确实,它给你很多控制参数。我需要curve.c不能生成的曲线,所以我写了一些脚本来弥补这些空缺。后来我有了一个将这些随机脚本组合成一个工具并为其制作可视化界面的想法,类似于curve.js。我开始了这个项目,并有些得意忘形。最终的结果就是曲线球! 它是如何工作的?我早期的脚本非常基础,但我逐渐找到了很好的抽象来提高它的效果,使其更不繁琐。请求描述宇宙 Neverball的关卡由许多“画笔”组成。每个画笔是一小块几何图形。画笔的定义方式相当奇怪:每个画笔都是半空间的交集。如果你之前没听说过,那听起来可能有点吓人,所以让我解释一下。想象你这样形成一个画笔:首先,让你的画笔占据整个宇宙。然后,一次又一次地将宇宙切成两半,直到你剩下一个小片段。这听起来很奇怪,但有技术上的原因这样做,比如让碰撞代码更容易。现在,我们需要一种方法来在文本文件中描述这些形状。Neverball解析Quake地图格式,其中每个“切割”由平面中的三个点定义。这些点必须以特定的顺序出现;如果你错了,可能会意外切掉宇宙的错误一半!如果你感兴趣,这里是一个立方体数据的示例:{ "classname" "worldspawn" // 画笔 0 { ( 0 0 64 ) ( 0 64 64 ) ( 64 0 64 ) mtrl/invisible 0 0 0 0.5 0.5 0 0 0 ( 0 0 0 ) ( 0 0 64 ) ( 64 0 64 ) mtrl/invisible 0 0 0 0.5 0.5 0 0 0 ( 0 0 64 ) ( 0 0 0 ) ( 0 64 64 ) mtrl/invisible 0 0 0 0.5 0.5 0 0 0 ( 64 0 64 ) ( 64 64 64 ) ( 64 64 0 ) mtrl/invisible 0 0 0 0.5 0.5 0 0 0 ( 64 64 0 ) ( 64 64 64 ) ( 0 64 64 ) mtrl/invisible 0 0 0 0.5 0.5 0 0 0 ( 0 0 0 ) ( 64 0 0 ) ( 64 64 0 ) mtrl/invisible 0 0 0 0.5 0.5 0 0 0 } } 点的坐标在括号中。之后的一切都与纹理有关。 凸性 不幸的是,画笔的工作方式意味着每个画笔必须是凸的。然而,大多数曲线都不是凸的。因此,曲线通常需要由许多较小的画笔组成。一种简单的方法是curve.c和我早期的脚本只是手动仔细选择点。这真的容易出错,且颇为麻烦。事实证明,我们的问题是可以使用凸包算法解决的。我找到了chull crate,它在Rust中实现了凸包算法。现在我可以给chull一堆点,让它帮我计算出如何用它们制作我的形状。太酷了!这使得快速组合新的曲线生成器变得简单。然而,这也使得为每个面分配纹理变得痛苦。Trenchbroom可以让我们快速地在很多面上涂抹纹理,因此我选择不去担心这个。使用chull让我通过定义顶点轻松生成这些曲线。但还有更多改进的空间。 关键思想:拉伸 我发现了一种非常有趣的抽象,用于生成这些曲线。它的灵感来自于机械CAD软件,如Solidworks。这个想法是,您定义一个2D轮廓,然后将其拉伸到3D空间中。在曲线球中,2D轮廓沿路径复制多次。曲线球然后将两个相邻面的所有顶点运行通过chull,生成一个画笔。重复此步骤,直到到达路径的末尾,那么曲线就生成了。这让生成形状的过程感觉非常自然,而且开启了许多选项。每个轮廓和路径的组合都会形成一个新的曲线。有些非常奇怪,可能没什么用,但你可以用它制作出很多有趣的、有用的曲线。如果我编写$m$个不同的轮廓和$n$条不同的路径,现在我可以生成$m imes n$种不同的曲线!手动编码每种排列会耗费很长时间。 定方向 一个有趣的问题是沿路径旋转轮廓。这对于旋转路径来说尤其自然,但对于其他路径也很有用。我在编程这个问题时遇到了麻烦。我的初步尝试失败了,因为它们都有同样的误解。事实证明,路径的点和你要前进的方向并不足以了解你应该如何旋转!
本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。
☕请我喝杯咖啡