带摩擦力的运动算法
Movement algorithm with friction
比如我有一个水平跟随鼠标的对象,它的最小位置是100,最大是200。
在此范围内,它是线性跟随鼠标的,即1个鼠标位置等于1个对象位置。
现在,如果鼠标在范围之外(低于 100,或高于 200),我希望它开始施加摩擦力,以便对象在距离范围越远的地方优雅地停止,例如:
Mouse position | Object position
200 200
220 205
240 209
260 212
280 215
300 217
320 218
340 219
360 220
380 220
400 220
...
我设法在鼠标移动处理程序中像这样实现它:
if (mousePosition > 200 || mousePosition < 100) {
delta = mousePosition - objectPosition;
objectPosition += delta * 0.25; // 0.25 if friction factor
}
但是有没有更好的办法呢?如何在鼠标移动处理程序之外实现功能:
getObjectPosition(mousePosition) {
return // ???
}
问题与语言无关。
您可以将对象位置计算为鼠标位置的分段函数:
getObjectPosition(mousePosition) {
if(mousePosition < 100)
return 100 - friction(100 - mousePosition);
if(mousePosition > 200)
return 200 + friction(mousePosition - 200);
return mousePosition;
}
其中friction
是计算你想要的"soft"函数的函数。一个简单的是:
friction(x) {
return 0.25*x;
}
当物体超出 [100, 200] 范围时,它会将物体速度降低 0.25。不过,您的功能似乎接近某种渐近线。例如,您可以使用二次方来实现它:
friction(x) {
M = 160;
x = min(x, M);
return x*(1 - x/(2*M));
}
这里物体会逐渐减速,当鼠标在[-60, 360]区间外时完全停止。
比如我有一个水平跟随鼠标的对象,它的最小位置是100,最大是200。
在此范围内,它是线性跟随鼠标的,即1个鼠标位置等于1个对象位置。
现在,如果鼠标在范围之外(低于 100,或高于 200),我希望它开始施加摩擦力,以便对象在距离范围越远的地方优雅地停止,例如:
Mouse position | Object position
200 200
220 205
240 209
260 212
280 215
300 217
320 218
340 219
360 220
380 220
400 220
...
我设法在鼠标移动处理程序中像这样实现它:
if (mousePosition > 200 || mousePosition < 100) {
delta = mousePosition - objectPosition;
objectPosition += delta * 0.25; // 0.25 if friction factor
}
但是有没有更好的办法呢?如何在鼠标移动处理程序之外实现功能:
getObjectPosition(mousePosition) {
return // ???
}
问题与语言无关。
您可以将对象位置计算为鼠标位置的分段函数:
getObjectPosition(mousePosition) {
if(mousePosition < 100)
return 100 - friction(100 - mousePosition);
if(mousePosition > 200)
return 200 + friction(mousePosition - 200);
return mousePosition;
}
其中friction
是计算你想要的"soft"函数的函数。一个简单的是:
friction(x) {
return 0.25*x;
}
当物体超出 [100, 200] 范围时,它会将物体速度降低 0.25。不过,您的功能似乎接近某种渐近线。例如,您可以使用二次方来实现它:
friction(x) {
M = 160;
x = min(x, M);
return x*(1 - x/(2*M));
}
这里物体会逐渐减速,当鼠标在[-60, 360]区间外时完全停止。