气球弦逆运动学
Balloon string inverse kinematics
我有一个模拟,其中我的气球在屏幕上弹跳,每个气球都附有一根绳子。它的功能就像一个约束。绳子应该服从重力,这样如果气球不是最大长度,应该松弛下垂。
为了解决这个问题,我用线段表示字符串。我让绳子开始垂直向下悬挂,然后遍历每个部分,将它指向气球,然后定位它以便连接。这使得行为非常接近我想要的,但是为了确保它不会离开中心,我将它转换回它根植的地方。问题是结束不再是连接的。如果我不必将字符串重置为垂直位置,这会起作用,但我必须这样做才能确保计算出松弛度。
我添加了一个临时解决方案,再次迭代它以重新连接它,行为是体面的,但它绝对不现实。可以在这里看到一个例子:http://www.mikerkoval.com/simulation/balloons
单击以创建气球。我不确定如何模拟重力。有没有更好的方法使这更现实?
-----编辑----
我正在努力解决悬链线函数中的 a 值。
我将函数定义为:
var k = function (a){
return Math.pow((2 * a[0]*Math.sinh(h/(2 * a[0])) - sqrt(s*s- v*v)), 2)
}
然而,当我调用
var sol = numeric.uncmin(k, [1]);
它运行了一会儿然后抛出一个 Nan 错误。我试图弄清楚问题出在哪里,但我收效甚微,因为我正在努力了解 uncmin
发生了什么
我想你想要的是通过p0
和p1
两个点找到悬链线的参数,锚点和气球的位置,给定弧长s
,这是字符串的长度。
曲线的方程为
y = a cosh (x / a)
其中 a
是您需要确定的参数。让 v
= y1
- y0
和 h
= x1
- h0
。通过一些代数,您可以证明 a
的值必须满足
sqrt(s*s - v*v) = 2 * a * sinh(h / (2a))
This article a nice discussion of how to solve this for a
iteratively with Newton's method。作者对变量b = a/h
进行了代入,使解space接近线性,因此牛顿会很快收敛到一个好的答案。
牛顿法是一种简单的迭代,需要曲线的显式导数和起点。上面的文章给出了导数。因为曲线非常接近线性,所以您可以选择该线性部分上的任何起点 - b = 0.2
即可。通过快速收敛,我的意思是每次迭代时正确有效数字的数量都会翻倍。因此在实践中,您可能会在 6 次或更少的迭代中获得双精度浮点数的所有数字。
一旦你有了参数,绘制你需要的显式曲线将是一个简单的模式。
如果 Newton 在 6 次左右的迭代中没有 收敛,那么问题的实例是一个非常病态的实例。在这里,这意味着一条非常接近直线的曲线。所以在 p0
和 p1
!
之间画一条线就行了
所有这些都应该足够快:比您当前的近似值便宜。
我有一个模拟,其中我的气球在屏幕上弹跳,每个气球都附有一根绳子。它的功能就像一个约束。绳子应该服从重力,这样如果气球不是最大长度,应该松弛下垂。
为了解决这个问题,我用线段表示字符串。我让绳子开始垂直向下悬挂,然后遍历每个部分,将它指向气球,然后定位它以便连接。这使得行为非常接近我想要的,但是为了确保它不会离开中心,我将它转换回它根植的地方。问题是结束不再是连接的。如果我不必将字符串重置为垂直位置,这会起作用,但我必须这样做才能确保计算出松弛度。
我添加了一个临时解决方案,再次迭代它以重新连接它,行为是体面的,但它绝对不现实。可以在这里看到一个例子:http://www.mikerkoval.com/simulation/balloons
单击以创建气球。我不确定如何模拟重力。有没有更好的方法使这更现实?
-----编辑----
我正在努力解决悬链线函数中的 a 值。
我将函数定义为:
var k = function (a){
return Math.pow((2 * a[0]*Math.sinh(h/(2 * a[0])) - sqrt(s*s- v*v)), 2)
}
然而,当我调用
var sol = numeric.uncmin(k, [1]);
它运行了一会儿然后抛出一个 Nan 错误。我试图弄清楚问题出在哪里,但我收效甚微,因为我正在努力了解 uncmin
发生了什么我想你想要的是通过p0
和p1
两个点找到悬链线的参数,锚点和气球的位置,给定弧长s
,这是字符串的长度。
曲线的方程为
y = a cosh (x / a)
其中 a
是您需要确定的参数。让 v
= y1
- y0
和 h
= x1
- h0
。通过一些代数,您可以证明 a
的值必须满足
sqrt(s*s - v*v) = 2 * a * sinh(h / (2a))
This article a nice discussion of how to solve this for a
iteratively with Newton's method。作者对变量b = a/h
进行了代入,使解space接近线性,因此牛顿会很快收敛到一个好的答案。
牛顿法是一种简单的迭代,需要曲线的显式导数和起点。上面的文章给出了导数。因为曲线非常接近线性,所以您可以选择该线性部分上的任何起点 - b = 0.2
即可。通过快速收敛,我的意思是每次迭代时正确有效数字的数量都会翻倍。因此在实践中,您可能会在 6 次或更少的迭代中获得双精度浮点数的所有数字。
一旦你有了参数,绘制你需要的显式曲线将是一个简单的模式。
如果 Newton 在 6 次左右的迭代中没有 收敛,那么问题的实例是一个非常病态的实例。在这里,这意味着一条非常接近直线的曲线。所以在 p0
和 p1
!
所有这些都应该足够快:比您当前的近似值便宜。