[原][算法][earth]三段smooth,传入时间,返回距离。仿谷歌视角飞跃处理
Posted lyggqm
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[原][算法][earth]三段smooth,传入时间,返回距离。仿谷歌视角飞跃处理相关的知识,希望对你有一定的参考价值。
算法需求:
传入【0~1】的时间time,返回【0~1】的路程。
整个路程distance【0~1】分为三段路径:
第一段:在0.25time的时间里,速度从0,位置从distance:0加速移动到距离distance:K
第二段:在0.25time时间里,位置从distance:k减速移动到某距离distance:1 – ratio
第三段:在0.5time时间里,位置从distance:1 – ratio减速移动到distance:1
但是变化率由第一段1/4总时间经过的路程K和总路程长度distance大小决定:如果总路程超过10000米,。如果总路程不超过10000米,第三段就用0.2*distarationce
已知参数:
|
初速度 |
末速度 |
时间 |
距离 |
路程 |
加速度 |
距离与时间算法 |
第一段 |
0 |
|
0.25 |
K |
K |
|
|
第二段 |
|
|
0.25 |
Ratio-k |
1-Ratio |
|
|
第三段 |
|
0 |
0.5 |
Ratio |
1 |
|
|
第一段推导算法与参数
S = A * time * time / 2
A = S / time * time
V = S * time
|
初速度 |
末速度 |
时间 |
距离 |
路程 |
加速度 |
距离与时间算法 |
第一段 |
0 |
8k |
0.25 |
K |
K |
32k |
Time * time *16K |
第二段 |
8K |
|
0.25 |
Ratio-k |
1-Ratio |
|
|
第三段 |
|
0 |
0.5 |
Ratio |
1 |
|
|
第三段推导算法与参数
S = A * time * time / 2
A = S / time * time
V = S * time
S = V *time + A * time * time / 2
|
初速度 |
末速度 |
时间 |
距离 |
路程 |
加速度 |
距离与时间算法 |
第一段 |
0 |
8k |
0.25 |
K |
K |
32k |
Time * time *16K |
第二段 |
8K |
4Ratio |
0.25 |
Ratio-k |
1-Ratio |
|
|
第三段 |
4Ratio |
0 |
0.5 |
Ratio |
1 |
-8Ratio |
1 –(1 – Time) *(1 – Time)*4Ratio |
接下来是第二段的推导,参数很多,似乎不用推导,但是突然发现,其实参数太多导致推导由问题:如果加速度A是固定的:
- A = 2*S/time*time 即: 32*(Ratio - k)
- A = (V1-V0)/time 即:4*(4Ratio - 8K)
32*(Ratio - k) = 4*(4Ratio - 8K)
为了满足以上算例,Ratio必须为0才行,这样不符合我们的预期。
我试了各种办法也没有能力让第二段保持这种状态,所以我舍弃第二段的初速度,使得第二段与第三段的初速度能连接。
|
初速度 |
末速度 |
时间 |
距离 |
路程 |
加速度 |
距离与时间算法 |
第一段 |
0 |
8k |
0.25 |
K |
K |
32k |
Time * time *16K |
第二段 |
|
4Ratio |
0.25 |
Ratio-k |
1-Ratio |
|
|
第三段 |
4Ratio |
0 |
0.5 |
Ratio |
1 |
-8Ratio |
1 –(1 – Time) *(1 – Time)*4Ratio |
继续推导第二段:
S = V0 * TIME + A * TIME * TIME /2
V1 = V0 + A * TIME
à
1 - Ratio - k = v0 /4 + a / 32
4Ratio = v0 + a / 4
à
A = 32 * (k + 2Ratio - 1)
V0 = 4 * Ratio – 8 * k
|
初速度 |
末速度 |
时间 |
距离 |
路程 |
加速度 |
距离与时间算法 |
第一段 |
0 |
8k |
0.25 |
K |
K |
32k |
Time * Time *16K |
第二段 |
8-8k-12Ratio |
4Ratio |
0.25 |
1-Ratio-k |
1-Ratio |
32k+64Ratio-32 |
|
第三段 |
4Ratio |
0 |
0.5 |
Ratio |
1 |
-8Ratio |
1 –(1 – Time) *(1 – Time)*4Ratio |
注意:为了保障第二段的初速度大于零:需要Ratio < 2/3 * ( 1 - k)
第一段距离时间函数:time < 0.25
Time * Time *16K
第二段距离时间函数:time < 0.5
K + (8-8k-12Ratio)*Time + (16k+32Ratio-16)*Time*Time
第三段距离时间函数:time < 1
1 –(1 – Time) *(1 – Time)*4Ratio
1 //将前0到0.8的距离用0到0.2的时间完成,后0.8到1的距离用0.2到1的时间完成 2 //传入的是时间0~~~0.2~~~1 3 //返回的是距离0~~~0.8~~~1 4 //pathLength是总距离,作为加减速参考值 5 //timeRatio传入的是时间t 返回的是移动距离S(当前位置) 6 double GY_threeSectionSmooth(double timeRatio, double pathLength = 100000.0) 7 { 8 // 9 // 初速度 末速度 时间 距离 路程 加速度 距离与时间算法 10 // 第一段 0 8k 0.25 K K 32k Time * Time * 16K 11 // 第二段 8 - 8k - 12Ratio 4Ratio 0.25 1 - Ratio - k 1 - Ratio 32k + 64Ratio - 32 K + (8 - 8k - 12Ratio)*Time + (16k + 32Ratio - 16)*Time*Time 12 // 第三段 4Ratio 0 0.5 Ratio 1 - 8Ratio 1 –(1 – Time) *(1 – Time) * 4Ratio 13 // 14 // 定义:k是第一段的路程,Ratio是第三段的路程 15 // 注意:为了保障第二段的初速度大于零:需要Ratio < 2 / 3 * (1 - k) 16 // 例如 k定义为0.6时,Ratio不能大于0.26 17 // 18 // 第一段距离时间函数:time < 0.25 19 // Time * Time * 16K 20 // 第二段距离时间函数:time < 0.5 21 // K + (8 - 8k - 12Ratio)*Time + (16k + 32Ratio - 16)*Time*Time 22 // 第三段距离时间函数:time < 1 23 // 1 –(1 – Time) *(1 – Time) * 4Ratio 24 25 //定义k 26 double k = 0.6; 27 28 //计算Ratio 注意:Ratio < 2/3 * ( 1 - k) 29 double pathRatio = pathLength / 10000.0; 30 pathRatio = std::max(1.0, pathRatio); 31 double ratio = 0.2 / pathRatio; 32 ratio = std::min(ratio, 2.0/3.0*(1.0-k)); 33 34 35 //计算三段位置与时间关系 36 double distanceRatio = timeRatio; 37 if (timeRatio < 0.25) //第一段:Time * Time * 16K 38 { 39 distanceRatio = k*timeRatio*timeRatio * 16; 40 } 41 else if (timeRatio < 0.5) //第二段:K + (8 - 8k - 12Ratio)*Time + (16k + 32Ratio - 16)*Time*Time 42 { 43 timeRatio -= 0.25; 44 distanceRatio = k + (8 - 8 * k - 12 * ratio) * timeRatio + (16 * k + 32 * ratio - 16) * timeRatio * timeRatio; 45 } 46 else if (timeRatio <= 1.0) //第三段:1 –(1 – Time) *(1 – Time) * 4Ratio 47 { 48 distanceRatio = 1 - (1 - timeRatio)* (1 - timeRatio) * 4 * ratio; 49 } 50 51 //logInfo("time: " + float_to_String(timeRatio) + " distance: " + float_to_String(distanceRatio) + " pathLength: " + float_to_String(pathLength) + " ratio: " + float_to_String(ratio)); 52 53 return distanceRatio; 54 }
以上是关于[原][算法][earth]三段smooth,传入时间,返回距离。仿谷歌视角飞跃处理的主要内容,如果未能解决你的问题,请参考以下文章
[原][译][osgearth]API开发地球(OE官方文档翻译)
负载均衡算法--平滑加权轮询法(Smooth Weight Round Robin)