粒子动力学

时间:2018-02-22 16:06:42

标签: algorithm game-physics

我在3D空间中建模粒子。

Particle Interpolation

{0}粒子在时间t0从具有速度V0的已知位置P0开始。使用其在t-1处的已知先前P-1位置来计算速度。

{1}粒子的目标是在t1以P1的已知速度进入P1。

{..}粒子尽可能快地移动,没有抖动(C1连续)由一组约束限制,这些约束独立地沿x,y和z钳制加速度。沿x,y和z的最大加速度/减速度是已知的并且是Xa,Ya和Za。沿x,y和z的最大加速度变化率由Xr,Yr和Zr定义。

{n}经过一定数量的时间步长后,它会在某个时间(比如tn)以速度Vn到达Pn。

{n + 1}它在tn + 1处移动到Pn + 1.

我遇到的问题是计算从P0到Pn的转换的最小时间,并生成其中间位置和速度方向。第二个目标是平滑加速,而不是应用导致混乱的加速度。

当前方法:

  1. 找到从开始P0到结束Pn最长对齐的尺寸{x,y或z}。这将是关键维度,并将决定总时间。这是相当简单的,我可以写一些这样的效果。

  2. 在所有维度上平滑插值而没有从P0到Pn的抖动,使得Pn处的速度与预期一致。我不确定,如何处理这个问题。

  3. 任何已经执行此操作的输入/物理引擎都将非常有用。这是一个商业项目,我无法依赖具有限制性许可的大型第三方库。

    注意:P0和Pn处的粒子几乎没有加速度。

2 个答案:

答案 0 :(得分:5)

如果我理解正确,您有一个点(P0, V0)V0 = P0 - P-1和点(Pn, Vn)Vn = Pn - Pn-1,您想要找到最少的中间点通过调整每个时间步的加速度。

让我们使用ti定义Ai = Vi - Vi-1abs(Ai) <= mA的加速度。这里,由于问题是与轴无关的,abs是成员方式绝对而不是范数(或向量大小),mA是最大加速度向量,每个维度为正。我们还要考虑Pn > P0(成员)。

由此,我们得到Vi = Vi-1 + Ai,因此Pi = Pi-1 + Vi-1 + Ai

如果你需要以最快的方式从一个点到另一个点,无论初始速度如何,显而易见的事情是尽可能加速直到达到目标。但是,由于您的问题是离散的并且您的终端速度为Vn,因此使用该方法可能会导致距离太远且终端速度不同。

但是,从结束点开始,您可以反过来做同样的事情。如果你从两个点同时开始,你将在每个维度上使两条路径彼此交叉(不一定在3D中交叉,但是,在每个维度中,两条路径的相对方向在某个“交叉”点处改变)。

我们来看一个一维的例子。 (P0, V0) = (0, -2)(Pn, Vn) = (35, -1)以及mA = 1 使用Ai = mA的第一条路径如下:

(0, -2) -> (-1, -1) -> (-1, 0) -> (0, 1) -> (2, 2) ->
(5, 3) -> (9, 4) -> (14, 5) -> (20, 6) -> (27, 7) -> ...

第二条路径Ai = -mA但反之亦然:

(35, -1) <- (36, 0) <- (36, 1) <- (35, 2) <- (33, 3) <-
(30, 4) <- (26, 5) <- (21, 6) <- (15, 7) <- ...

您可以看到路径在20到21之间以相同的速度交叉。这为您提供了所需路径中最快的加速和减速部分,但这两个部分没有连接。但是,通过找到相同速度的最近点可以很容易地连接它们;我们称这些点为PqPr。在此处Pq = (20, 6)Pr = (21, 6)。由于该速度是在当前点和先前点之间计算的,因此请在Pq(示例中为Pq-1(14, 5))和点Pr之前取点,然后尝试连接它们

如果Pq >= Pr >= Pq - 2mA,则可以通过Pq-1保持不变来直接连接它们,将PrVr = Pr - Pq-1保持一致。

否则,请Pq-2Pr-1Vr-1 = Vr - mA,因为它正好相反)并尝试通过添加中间点来连接它们。由于这些点的速度差为mA,因此您只能搜索具有相同速度Vs的中间点,以便Vq-2 <= Vs <= Vr-1

如果仍然无法找到解决方案,请执行Pq-3Pr-2并使用更多中间点重复此过程。

在我拍摄的示例Pq < Pr中,我们必须尝试使用​​Pq-2 = (9, 4)Pr-1 = (26, 5)。我们可以连接具有3个点的序列,例如(9, 4) -> (13, 4) -> (17, 4) -> (21, 4) -> (26, 5)

在任何情况下,此方法都会为您提供最少量的中间点,这意味着P0Pn之间的最快路径。

如果你想减少加加速度,那么你可以忘记先前计算的点,并使用你现在知道的最小点的进行插值。

答案 1 :(得分:3)

在尝试了一些想法之后,我提出了另一种解决方案,如果做得正确,可能比我以前的答案更准确,也可能更快。然而它很复杂,需要相当多的数学,虽然不是很复杂的数学。此外,这是一项正在进行的工作:我仍在调查一些领域。尽管如此,根据我的尝试,它已经产生了非常好的结果。

问题

定义和目标

在这个答案中,p[n]指的是第n个点的位置,v[n]指向其速度,a[n]表示其加速度,j[n]表示其加速度(p[0]指向其加速度加速度的导数)。第n点的速度仅取决于其位置和前一点的位置。同样对于加速度和加速度,但分别用点速度和加速度。

我们分别有p[n]v[0]的起点和终点,两者都有关联的速度v[n]n-1。我们的目标是在n之间放置p[n]个点,使其沿着X,Y和Z轴,在这些点的任何一个点上加速度和加加速度的绝对值(和在aMaxX)低于某些限制,分别为aMaxYaMaxZjMaxX加速,jMaxYjMaxZ和{{ 1}} for jerk。

我们想要找到的是p[i]对所有i ∈ [1; n-1]的值。因为p[i] = p[i-1] + v[i],这与查找v[i]相同。根据相同的推理,使用v[i] = v[i-1] + a[i]a[i] = a[i-1] + j[i],它也与查找a[i]j[i]相同。

假设{p> a[0]a[n+1]为零。

观察和简化

由于问题的约束与维度无关,我们可以分别求解三个维度中的每一个,只要在每种情况下获得的点数相同即可。因此,我只会使用aMaxjMax来解决问题的一维版本,而不管轴是什么。

* [WIP] *确定要解决的最坏情况,然后解决其他问题,了解点数。

两个给定点的实际位置无关紧要,重要的是它们之间的相对距离,我们可以将其定义为P = p[n] - p[0]。我们还要定义范围R = [1; n]R* = [1; n+1]

由于问题的离散性,我们可以得到以下等式。请注意,∑{i∈R}(x[i])x[i]的所有i∈R的总和。

Ⓐ ∑{i∈R}(v[i]) = P
Ⓑ ∑{i∈R}(a[i]) = v[n] - v[0]
Ⓧ ∑{i∈R*}(j[i]) = 0

Ⓧ来自a[0] = a[n+1] = 0的假设 从Ⓐ和v[i] = v[i-1] + a[i], i∈R,我们可以推断:

Ⓒ ∑{i∈R}((n+1-i)*a[i]) = P - n*v[0]

按照相同的逻辑,从Ⓑ,Ⓒ和a[i] = a[i-1] + j[i], i∈R,我们可以推断:

Ⓨ ∑{i∈R}((n+1-i)*j[i]) = v[n] - v[0]
Ⓩ ∑{i∈R}(T[n+1-i]*j[i]) = P - n*v[0]

此处,T[n]是第n个三角形数字,由T[n] = n*(n+1)/2定义。

方程式Ⓧ,Ⓨ和Ⓩ是下一部分的相关方法。

方法

为了最小化n,我们可以从较小的n(1,2?)开始,找到解决方案。然后,如果max{i∈R}(abs(a[i])) > aMaxmax{i∈R}(abs(j[i])) > jMax,我们可以增加n并重复此过程。

* [WIP] *查找n的下限,以避免从n的小值进行不必要的计算。或者估算n的正确值并通过测试解决方案来确定它。

查找解决方案需要为所有j[i]找到i∈R*的值。我还没有找到j[i]的最佳表单,但定义j*[i]r[i]s[i]这样 j[i] = j*[i] + r[i]v[0] + s[i]v[n]
效果很好。

* [WIP] *为j[i]

找到更好的表单

通过这样做,我们将n-1未知数(j[i], i∈R,请注意j[n+1] = -∑{i∈R}(j[i]))转换为3(n-1)更容易找到未知数。以下是我们现在可以从Ⓧ,Ⓨ和dedu中推断出的一些事情。

∑{i∈R*}(r[i]) = 0
∑{i∈R*}(s[i]) = 0
∑{i∈R}((n+1-i)*r[i]) = -1
∑{i∈R}((n+1-i)*s[i]) = 1
∑{i∈R}(T(n+1-i)*r[i]) = -n
∑{i∈R}(T(n+1-i)*s[i]) = 0

提醒一下,这里有Ⓧ,Ⓨ和Ⓩ。

Ⓧ ∑{i∈R*}(j[i]) + j[n+1] = 0
Ⓨ ∑{i∈R}((n+1-i)*j[i]) = v[n] - v[0]
Ⓩ ∑{i∈R}(T[n+1-i]*j[i]) = P - n*v[0]

现在的目标是找到足够的特殊情况来帮助我们确定这些未知数。

特殊情况

v[0] = v[n] = 0

通过玩jerk的值,我观察到将所有j[i], i∈R*作为抛物线的一部分产生了极好的结果,可以最小化加加速度和加速度。虽然它不是最合适的,但我还没有找到更好的效果。

来自抛物线的混蛋值背后的直觉是,如果位置的值要遵循多项式,那么它的度必须至少为5,并且可以是5.如果你想到的话,这更容易理解4次多项式后的速度值。 v[0]v[n]设置的约束a[0] = a[n+1] = 0以及[0; n]上的积分必须等于P,此多项式必须至少具有一定的度数这适用于连续和双重情况。最后,似乎采用最小程度可以使得更加平滑,并且更容易计算。

这是一个连续情况的例子,其中位置为紫色,速度为蓝色,加速度为黄色,加速度为红色。

Example curves for position, velocity, acceleration, and jerk

如果您想要使用此功能,以下是根据np[0]p[n]v[0]和{{来定义位置曲线的方法1}}(其他的只是衍生物)。

v[n]

如果a = (-3(v[n]+v[0]) + 6(p[n]-p[0])) / n^5 b = (n(7v[n]+8v[0]) - 15(p[n]-p[0])) / n^4 c = (-n(4v[n]+6v[0]) + 10(p[n]-p[0])) / n^3 p[x] = ax^5 + bx^4 + cx^3 + v[0]x + p[0] ,则v[0] = v[n] = 0。这意味着值j[i] = j*[i], i∈R*遵循二次多项式。因此,我们希望找到j*[i]αβ,以便Ⓟ持有。

γ

从Ⓧ,Ⓨ和Ⓩ遵循这些等式。

Ⓟ j*[i] = αi^2 + βi + γ, i∈R*

解决此系统会提供α*∑{i∈R*}(i^2) + β*∑{i∈R*}(i) + c*∑{i∈R*}(1) = 0 α*∑{i∈R}((n+1-i)*i^2) + β*∑{i∈R}((n+1-i)*i) + c*∑{i∈R}(n+1-i) = 0 α*∑{i∈R}(T(n+1-i)*i^2) + β*∑{i∈R}(T(n+1-i)*i) + c*∑{i∈R}(T(n+1-i)) = P αβ,可与Ⓟ一起使用来计算γ。请注意j*[i], i∈R*,因此只需要完成计算的上半部分。

j*[i] = j*[n+2-i]

如果v[0] = v[n] = 1/n,则v[0] = v[n] = 1/n。这意味着Ⓠ持有。

j[i] = 0, i∈R*

Ⓠ r[i] + s[i] = -n*j[i], i∈R*

v[0] = 0, j[i∈L] = J, j[h] = 0, j[i∈U] = -JL分别是U的下半部分和上半部分,如果R*是奇数,则h是两者之间的值。换句话说:

n+1

此特殊情况对应于if n is odd: L = [1; (n+1)/2] U = [(n+3)/2; n+1] if n is even: L = [1; n/2] h = n/2+1 U = [n/2+2; n] p[0]之间的最大总加速度,同时最小化p[n]。在这里,Ⓩ给出了以下等式。

abs(j[i]), i∈R*

这会∑{i∈R}(T[n+1-i]*j[i]) = P ∑{i∈L}(T[n+1-i])*j[1] + ∑{i∈U}(T[n+1-i])*j[n+1] = P j[1] = P / [ ∑{i∈L}(T[n+1-i]) - ∑{i∈U}(T[n+1-i]) ] ,所以每j[1]。然后,我们可以使用Ⓨ。

计算j[i], i∈R*

将各个部分放在一起

对于v[n]v[0]v[n]的某些值,每个特殊情况都会为我们提供形式的关系
P
通过处理三个特殊情况(假设它们不相似,意味着不给出相同的关系),我们有一个由三个方程组成的系统,一旦求解,就会给出αj*[i] + βr[i] + γs[i] = δj*[i]的值和所有r[i]都是s[i]

因此,我们可以为i∈R*的每个值计算n的值,具体取决于j[i]v[0]v[n]。它们可以预先计算,这意味着可以非常快速地测试P的任何值。因此,只要我们将预先计算的值达到{{1 }}