我在3D空间中建模粒子。
{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的转换的最小时间,并生成其中间位置和速度方向。第二个目标是平滑加速,而不是应用导致混乱的加速度。
找到从开始P0到结束Pn最长对齐的尺寸{x,y或z}。这将是关键维度,并将决定总时间。这是相当简单的,我可以写一些这样的效果。
在所有维度上平滑插值而没有从P0到Pn的抖动,使得Pn处的速度与预期一致。我不确定,如何处理这个问题。
任何已经执行此操作的输入/物理引擎都将非常有用。这是一个商业项目,我无法依赖具有限制性许可的大型第三方库。
注意:P0和Pn处的粒子几乎没有加速度。
答案 0 :(得分:5)
如果我理解正确,您有一个点(P0, V0)
,V0 = P0 - P-1
和点(Pn, Vn)
,Vn = Pn - Pn-1
,您想要找到最少的中间点通过调整每个时间步的加速度。
让我们使用ti
定义Ai = Vi - Vi-1
:abs(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之间以相同的速度交叉。这为您提供了所需路径中最快的加速和减速部分,但这两个部分没有连接。但是,通过找到相同速度的最近点可以很容易地连接它们;我们称这些点为Pq
和Pr
。在此处Pq = (20, 6)
和Pr = (21, 6)
。由于该速度是在当前点和先前点之间计算的,因此请在Pq
(示例中为Pq-1
或(14, 5)
)和点Pr
之前取点,然后尝试连接它们
如果Pq >= Pr >= Pq - 2mA
,则可以通过Pq-1
保持不变来直接连接它们,将Pr
与Vr = Pr - Pq-1
保持一致。
否则,请Pq-2
和Pr-1
(Vr-1 = Vr - mA
,因为它正好相反)并尝试通过添加中间点来连接它们。由于这些点的速度差为mA
,因此您只能搜索具有相同速度Vs
的中间点,以便Vq-2 <= Vs <= Vr-1
。
如果仍然无法找到解决方案,请执行Pq-3
和Pr-2
并使用更多中间点重复此过程。
在我拍摄的示例Pq < Pr
中,我们必须尝试使用Pq-2 = (9, 4)
和Pr-1 = (26, 5)
。我们可以连接具有3个点的序列,例如(9, 4) -> (13, 4) -> (17, 4) -> (21, 4) -> (26, 5)
。
在任何情况下,此方法都会为您提供最少量的中间点,这意味着P0
和Pn
之间的最快路径。
如果你想减少加加速度,那么你可以忘记先前计算的点,并使用你现在知道的最小点的数进行插值。
答案 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
)低于某些限制,分别为aMaxY
,aMaxZ
和jMaxX
加速,jMaxY
,jMaxZ
和{{ 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]
相同。
a[0]
和a[n+1]
为零。
由于问题的约束与维度无关,我们可以分别求解三个维度中的每一个,只要在每种情况下获得的点数相同即可。因此,我只会使用aMax
和jMax
来解决问题的一维版本,而不管轴是什么。
* [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])) > aMax
或max{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
,此多项式必须至少具有一定的度数这适用于连续和双重情况。最后,似乎采用最小程度可以使得更加平滑,并且更容易计算。
这是一个连续情况的例子,其中位置为紫色,速度为蓝色,加速度为黄色,加速度为红色。
如果您想要使用此功能,以下是根据n
,p[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] = -J
和L
分别是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 }}