4

模拟 flexagon 的最佳方法是什么?

我对起点的最佳猜测是表示面和边缘,并根据边缘相遇的位置模拟变换。我在想,在实现转换的过程中,当在给定方向上折叠在物理上是不可能的时,这将是显而易见的。

我将尝试通过实验来解决这个问题,但这绝对感觉像是我的数学能力差距阻碍了我的问题。

编辑:澄清一下,我对可以使用哪种数据结构来表示 flexagon 以及如何操纵这些数据结构来模拟 flexagon 的折叠感兴趣。

4

1 回答 1

2

如果将 flexagon 的所有不变量写为方程组,则合法状态周围的小偏差可以写为线性系统。例如,一张纸的硬度介于(x1,y1)(x2,y2)之间

(x1 - x2)**2 + (y1 - y2)**2 - L**2 == 0

这可以软化为

chi2 = (x1 - x2)**2 + (y1 - y2)**2 - L**2 + other constraints...

chi2关于x1, x2,y1的导数y2产生线性方程。线性方程组是一个矩阵,该矩阵的特征值/特征向量分解为您提供易于或难以弯曲的参数的x1线性x2组合。特征向量是一组可能的方向,每个对应的特征值告诉你在那个方向弯曲有多难。较大的特征值受到更多约束。y1y2

上面的一个问题是,如果真的有任何方向是允许的,即chi2关于的导数p为0(绝对满足原约束),那么矩阵是奇异的,不能求逆得到本征系统。如果您只想知道那些绝对允许的方向是什么,您可以计算矩阵的零空间而不是其特征系统。但是,我怀疑(从未玩过 flexagon)“允许”的方向涉及一点弯曲,在这种情况下chi2很小但非零。然后你会寻找小但非零的特征值。其他自由度是允许的且无意义的,例如整个对象的平移或旋转。要将其转换为纯特征系统问题(根本没有零空间),请使用任意小的常数 lambda 向系统添加约束:

chi2 += lambda_x * (x1 + x2)**2/4.0 + lambda_y * (y1 + y2)**2/4.0

你会在你的解决方案中认出它们,因为它们会随着你改变每个 lambda 而变化。(上面的例子给出了lambda_x在 xlambda_y中翻译和在 y 中翻译的惩罚。)

在实现方面,您可以使用任何线性代数软件来计算解决方案并检查 lambdas 的变化。我使用 Python 对这样的问题进行了原型设计(高能物理学中的探测器对齐,其中约束是测量值,例如“这个探测器距离那个探测器 3 厘米”和chi2源自不确定性“3 cm +- 0.1 cm”),然后将解决方案移植到 C++ (BLAS) 进行生产。Python 的 Numpy 库有足够的线性代数(它的底层是 BLAS),尽管我还在 Scipy 中使用了通用的非线性最小化器来调试矩阵解决方案。最难的部分是让索引正确排列,这在将其转换为矩阵时是必要的,而不是在将目标函数提供给通用最小化器时(因为您使用变量名)。这更像是一个 Matlab 或 Mathematica 问题,所以如果您对其中一个更满意,请改用它。这个问题需要大量的试验和错误,所以尽可能使用交互性最强的系统(具有良好 REPL 或工作表/笔记本式界面的系统)。

绘制连接图(图论图,而不是绘图)也很有帮助,在其上标记它们的约束。对我来说,这是写出方程式之前必要的第一步。

它还可能有助于通过编写一组函数来可视化系统,这些函数采用参数值(x1等)并使用 OpenGL(或其他 3-D 网格渲染器)绘制图形。这可以告诉您是否违反了某些约束,因为网格瓷砖会相互通过。它还可以帮助您识别每个特征向量表示的自由度:通过特征向量表示的线性组合改变参数,您将看到它是否只是平移/旋转,或者它是否正在做一些有趣的扭曲或折叠。

于 2013-07-14T19:37:27.690 回答