在尝试了一些想法之后,我想出了另一个解决方案,如果做得正确,比我之前的答案更准确,可能更快。然而,它相当复杂,需要相当多的数学,虽然不是很复杂的数学。此外,这是一项正在进行的工作:我仍在调查某些领域。尽管如此,从我的尝试来看,它确实已经产生了非常好的结果。
问题
定义和目标
在整个答案中,p[n] 指第 n 个点的位置,v[n] 指它的速度,a[n] 指它的加速度,j[n] 指它的 jerk(加速度的导数)。第 n 个点的速度只取决于它的位置和前一个点的位置。加速度和加加速度也类似,但分别是速度和加速度。
我们有一个起点和一个终点,分别是p[0] 和p[n],两者都有关联的速度v[0] 和v[n]。目标是将n-1 与任意n 点放在中间,这样,沿X、Y 和Z 轴,这些点(以及p[n])处的加速度和加加速度的绝对值) 低于某些限制,分别为 aMaxX、aMaxY 和 aMaxZ 用于加速,jMaxX、jMaxY 和 jMaxZ 用于混蛋。
我们想要找到的是所有i ∈ [1; n-1] 的p[i] 的值。因为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]) 是 i∈R 的所有 x[i] 的总和。
Ⓐ ∑{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的正确值,通过测试解决方案确定。
找到解决方案需要找到所有i∈R* 的j[i] 值。我还没有找到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)更容易找到未知数。以下是我们现在可以从Ⓧ、Ⓨ和Ⓩ推断出的一些内容。
∑{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* 作为抛物线的一部分会产生极好的结果,以最小化 jerk 和加速度。虽然它不是最合适的,但我还没有找到更好的。
jerk 值来自抛物线的直觉是,如果 position 的值遵循多项式,那么它的次数必须至少为 5,并且可以为 5。如果你考虑一下,这更容易理解遵循 4 次多项式的速度值。设置v[0] 和v[n] 的约束条件a[0] = a[n+1] = 0,并且它对[0; n] 的积分必须等于P,这个多项式的次数必须至少为4。这对于连续和离散情况都成立.最后,似乎取最小的度数会导致更平滑的混动以及更容易计算。
这是一个连续情况的示例,其中位置为紫色,速度为蓝色,加速度为黄色,加加速度为红色。
如果你想玩这个,这里是如何根据n、p[0]、p[n]、v[0] 和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* 的下半部分和上半部分,如果n+1 是奇数,h 是两者之间的值。换句话说:
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 的每个值,我们可以根据v[0]、v[n] 和P 计算j[i] 的值。它们可以预先计算,这意味着测试它们以获取n 的任何值都可以非常快。因此,只要我们预先计算出足够大的值 n .