- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
Gaffer on Games 有一个 great article关于使用RK4 integration为了更好的游戏物理。实现很简单,但其背后的数学让我感到困惑。我在概念层面上了解导数和积分,但已经很长时间没有操作过方程了。
这是 Gaffer 实现的主要部分:
void integrate(State &state, float t, float dt)
{
Derivative a = evaluate(state, t, 0.0f, Derivative());
Derivative b = evaluate(state, t+dt*0.5f, dt*0.5f, a);
Derivative c = evaluate(state, t+dt*0.5f, dt*0.5f, b);
Derivative d = evaluate(state, t+dt, dt, c);
const float dxdt = 1.0f/6.0f * (a.dx + 2.0f*(b.dx + c.dx) + d.dx);
const float dvdt = 1.0f/6.0f * (a.dv + 2.0f*(b.dv + c.dv) + d.dv)
state.x = state.x + dxdt * dt;
state.v = state.v + dvdt * dt;
}
有人可以简单地解释一下 RK4 的工作原理吗?具体来说,为什么我们要对 0.0f
、0.5f
、0.5f
和 1.0f 处的导数求平均值?
求四阶导数的平均值与使用较小时间步长进行简单的欧拉积分有何不同?
阅读下面已接受的答案以及其他几篇文章后,我了解了 RK4 的工作原理。回答我自己的问题:
谁能简单地解释一下 RK4 的工作原理吗?
RK4 takes advantage of the fact that we can get a much better approximation of a function if we use its higher-order derivatives rather than just the first or second derivative. That's why the Taylor series converges much faster than Euler approximations. (take a look at the animation on the right side of that page)
具体来说,为什么我们要对 0.0f
、0.5f
、0.5f
和 1.0 处的导数进行平均f
?
The Runge-Kutta method is an approximation of a function that samples derivatives of several points within a timestep, unlike the Taylor series which only samples derivatives of a single point. After sampling these derivatives we need to know how to weigh each sample to get the closest approximation possible. An easy way to do this is to pick constants that coincide with the Taylor series, which is how the constants of a Runge-Kutta equation are determined.
This article made it clearer for me. Notice how
(15)
is the Taylor series expansion while(17)
is the Runge-Kutta derivation.
求四阶导数的平均值与使用较小时间步长进行简单的欧拉积分有何不同?
Mathematically, it converges much faster than doing many Euler approximations. Of course, with enough Euler approximations we can gain equal accuracy to RK4, but the computational power needed doesn't justify using Euler.
最佳答案
就实际数学而言,这可能有点过于简单化,但它是作为 Runge Kutta
集成的直观指南。
给定某个时间 t1
的数量,我们想知道另一个时间 t2
的数量。通过一阶微分方程,我们可以知道该量在 t1 时的变化率。我们无法确定其他任何事情;剩下的就是猜测了。
欧拉积分是最简单的猜测方法:使用 t1
处精确已知的变化率从 t1
线性外推到 t2。这通常会给出一个不好的答案。如果 t2 远离 t1,则此线性外推法将无法匹配理想答案中的任何曲率。如果我们从 t1 到 t2 采取许多小步骤,我们就会遇到相似值相减的问题。舍入错误会破坏结果。
因此我们完善了我们的猜测。一种方法是继续进行线性外推,然后希望它不会与事实相差太远,使用微分方程来计算 t2
处的变化率估计值。该值与 t1
处的(准确)变化率进行平均,可以更好地代表 t1
和 t2
之间真实答案的典型斜率。我们用它来从 t1
到 t2
进行新的线性外推。我们是否应该采用简单平均值,或者对 t1
的速率给予更多权重,而不进行数学估计误差,这一点并不明显,但这里有一个选择。无论如何,这都是比欧拉给出的更好的答案。
也许更好的是,将我们的初始线性外推到 t1
和 t2
之间的中间时间点,并使用微分方程计算那里的变化率。这给出了与刚刚描述的平均值大致一样好的答案。然后使用它进行从 t1
到 t2
的线性外推,因为我们的目的是找到 t2
处的数量。这就是中点算法。
您可以想象使用变化率的中点估计来对从 t1
到中点的数量进行另一个线性外推。通过微分方程,我们可以更好地估计那里的斜率。使用这个,我们最终从 t1
一直推断到我们想要答案的 t2
。这就是龙格库塔
算法。
我们可以对中点进行第三次外推吗?当然,这并不违法,但详细的分析显示改进逐渐减弱,因此其他错误来源主导了最终结果。
龙格库塔将微分方程应用于初始点 t1,两次应用于中点,一次应用于最终点 t2。中间点是一个选择问题。可以使用 t1
和 t2
之间的其他点来改进斜率估计。例如,我们可以使用 t1
,一个指向 t2 的三分之一的点,另一个指向 t2
的 2/3 的点,以及位于 t2
的点。四个导数的平均值的权重会有所不同。在实践中,这并没有真正的帮助,但可能在测试中占有一席之地,因为它应该给出相同的答案,但会提供一组不同的舍入误差。
关于math - 用于游戏物理的 Runge-Kutta (RK4) 集成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1668098/
这个问题在这里已经有了答案: Converting result of Math.sin(x) into a result for degrees in java (4 个答案) 关闭 5 年前。
我在学习 Kotlin 并在数学课上遇到了这个问题: java.lang.Math 和 kotlin.math 不兼容。这对我来说有点尴尬和困惑,因为 Kotlin 声称它与 Java 100% 兼容
我在其他问题中读到,例如由于浮点表示,sin(2π) 不为零,但非常接近。这个非常小的错误在我的代码中不是问题,因为例如我可以四舍五入 5 位小数。 但是当2π乘以一个非常大的数时,误差就会放大很多。
我正在用 C# 编写一个计算器。 textBoxResult 是我显示数字的文本框 recount 是一个以度为单位的角度并以弧度为单位返回的函数 我从 texBoxInput 获取角度 public
首先,让我们从我的数学背景开始。我已经学习了微积分 I - IV 和微分方程。我参加了第一学期的计算机图形类(class),在该类(class)中我们实现了几乎我们自己的图形管道,包括使用 Phong
早上好! 我只是想磨练我的数学能力,我特别有一些关于 Cocos2D 的问题。由于 Cocos2D 想要“简化”事物,所有 Sprite 都有一个旋转属性,范围从 0-360(359?)CW。这迫使你
是否有人对Intel Math Kernel Library和AMD Math Core Library都有编程经验?我正在建立一台用于高性能统计计算的个人计算机,并对正在购买的组件进行辩论。 AMD
函数的反函数是什么 math.atan2 我在 Lua 中使用它,我可以通过 math.tan 获得 math.atan 的逆。 但我在这里迷路了。 编辑 好的,让我向您提供更多详细信息。 我需要计算
我有一道等轴测投影的数学题。我读了一篇文章:Axonometric projections - a technical overview .对于等距投影部分,它给出了将 x 部分的 3D 点转换为 2
在 MySQL (5.1) 数据库表中,有数据表示: 用户执行任务需要多长时间 用户在任务中处理了多少项目。 MySQL 是否支持关联数据,还是我需要使用 PHP/C# 来计算? 我在哪里可以找到计算
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 9 年前。 Improv
我正在尝试使用这两种方法在 C# 中解决这个问题: public double NormalPowerMethod(double x, double toPower) { return Mat
如何分配: var randomNumber = Math.random()*50 + Math.random()*20; 比较: var randomNumber = Math.random()*7
我正在查看我的代码,希望提高它的性能,然后我看到了这个: int sqrt = (int) Math.floor(Math.sqrt(n)); 哦,好的,我真的不需要调用 Math.floor,因为转
尝试调用 math.h 中的函数时, 我收到如下链接错误 undefined reference to sqrt 但我正在做一个 #include 我正在使用 gcc 并编译如下: gcc -Wall
祝大家有个愉快的一天,我有话要问你,为了更好地理解这里是我的代码: {math equation=((($order_total-$commission)+$discount+$delivery_ch
我尝试学习一些Clojure,因为该语言看起来不错。 但是似乎没有关于如何安装/使用库的信息,例如clojure.math.numeric-tower。 现在,我通过在Linux shell中键入以下
As Math.sign() 接受数字参数或数字作为字符串,如 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Gl
如何将scala.math.BigDecimal转换为java.math.BigDecimal? 最佳答案 无需在字符串之间进行双重转换。 val sb = scala.math.BigDecimal
为什么下面的 JavaScript 会这样 Math instanceof Math 抛出错误 TypeError: Expecting a function in instanceof check,
我是一名优秀的程序员,十分优秀!