pau*_*ode 10 java algorithm android android-vibration
我试图以编程方式生成Android振动模式,打开和关闭"微脉冲",以控制振动对最终用户的强度.这是我在一些类似主题中推荐的解决方案,即API没有提供控制振动强度的接口的问题(因为硬件的功能如我所知).
然而,用于生成这些模式的算法似乎只是暗示,但没有发布实际的算法.
我想要做的是,如果输入强度介于0.0f和1.0f之间,则会生成一个类似于以下模式的数组:
(zero intensity)
[20,0]
[9,1,9,1]
...
[3,1,3,1,3,1,3,1,3,1]
[2,1,2,1,2,1,2,1,2,1,2,1,2]
(half intensity)
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
[1,2,1,2,1,2,1,2,1,2,1,2,1,1]
[1,3,1,3,1,3,1,3,1,3]
...
[1,9,1,9]
(full intensity)
[0,20]
Run Code Online (Sandbox Code Playgroud)
编写这样的算法的任何帮助(或建议更好的策略来实现相同的目标)?
编辑:我已经添加了100个声望的赏金:)
pau*_*ode 11
在看了一会儿这个问题,而不是在数学上不是很有天赋之后,我想出了一个过于简化的算法(与我在Dithermaster指向那个方向后发现的一些PWM公式相比).我做的几个假设首先是短脉冲宽度始终为1,而长脉冲宽度是1和振动持续时间之间的整数.我还假设长脉冲宽度是振动强度的线性函数.特别是,后一种假设并不准确.我猜这个函数应该更像是分贝计算(振动的"强度"类似于声音的"响度").
发布我的简化解决方案,以防其他任何人在这里结束.这对于我正在使用它的应用程序足够接近,但我仍然想要更好的东西.如果有人发布替代答案,我会测试并接受它,如果它更好.
public long[] genVibratorPattern( float intensity, long duration )
{
float dutyCycle = Math.abs( ( intensity * 2.0f ) - 1.0f );
long hWidth = (long) ( dutyCycle * ( duration - 1 ) ) + 1;
long lWidth = dutyCycle == 1.0f ? 0 : 1;
int pulseCount = (int) ( 2.0f * ( (float) duration / (float) ( hWidth + lWidth ) ) );
long[] pattern = new long[ pulseCount ];
for( int i = 0; i < pulseCount; i++ )
{
pattern[i] = intensity < 0.5f ? ( i % 2 == 0 ? hWidth : lWidth ) : ( i % 2 == 0 ? lWidth : hWidth );
}
return pattern;
}
Run Code Online (Sandbox Code Playgroud)
假设总持续时间是n,而不是20.你的函数在强度i变化时会做两件事:
k(i)循环次数发生变化.它开始于k(0) = 1,峰值k(0.5) = n/2,然后下降到k(1) = 1.r(i)每对中的时间开/关时间的比例改变.如果我们有一个周期[a, b],那a就是时间和b休息时间r(i)*a = b.你的榜样去,我们有r(0) = 0,r(0.5) = 1,则渐近达r(1) = infinity有很多的,可以匹配函数k(i)和r(i),但让我们坚持用简单的:
k(i) = (int) (n/2 - (n-2)*|i - 0.5|) r(i) = 1 / (1.000001 - i) - 1
Run Code Online (Sandbox Code Playgroud)
其中|x|表示的绝对值x.我也取代1了1.000001中r的分母,这样我们就不必处理除以零错误.
现在如果循环需要求和n,那么任何一个循环的长度[a, b]都是n/k(i).既然我们也有r(i)*a = b,那么就是这样
a = n/(k*(1+r)) b = r*a
Run Code Online (Sandbox Code Playgroud)
为了形成强度阵列i,我们只需要重复[a, b] k一次.以下是输出的示例n = 20:
Intensity: 0.00, Timings: 20.0, 0.0
Intensity: 0.05, Timings: 9.5, 0.5, 9.5, 0.5
Intensity: 0.10, Timings: 6.0, 0.7, 6.0, 0.7, 6.0, 0.7
Intensity: 0.15, Timings: 4.3, 0.7, 4.3, 0.7, 4.3, 0.7, 4.3, 0.7
Intensity: 0.20, Timings: 3.2, 0.8, 3.2, 0.8, 3.2, 0.8, 3.2, 0.8, 3.2, 0.8
Intensity: 0.25, Timings: 2.5, 0.8, 2.5, 0.8, 2.5, 0.8, 2.5, 0.8, 2.5, 0.8, 2.5, 0.8
Intensity: 0.30, Timings: 2.0, 0.9, 2.0, 0.9, 2.0, 0.9, 2.0, 0.9, 2.0, 0.9, 2.0, 0.9, 2.0, 0.9
Intensity: 0.35, Timings: 1.6, 0.9, 1.6, 0.9, 1.6, 0.9, 1.6, 0.9, 1.6, 0.9, 1.6, 0.9, 1.6, 0.9, 1.6, 0.9
Intensity: 0.40, Timings: 1.3, 0.9, 1.3, 0.9, 1.3, 0.9, 1.3, 0.9, 1.3, 0.9, 1.3, 0.9, 1.3, 0.9, 1.3, 0.9, 1.3, 0.9
Intensity: 0.45, Timings: 1.1, 0.9, 1.1, 0.9, 1.1, 0.9, 1.1, 0.9, 1.1, 0.9, 1.1, 0.9, 1.1, 0.9, 1.1, 0.9, 1.1, 0.9, 1.1, 0.9
Intensity: 0.50, Timings: 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0
Intensity: 0.55, Timings: 0.9, 1.1, 0.9, 1.1, 0.9, 1.1, 0.9, 1.1, 0.9, 1.1, 0.9, 1.1, 0.9, 1.1, 0.9, 1.1, 0.9, 1.1, 0.9, 1.1
Intensity: 0.60, Timings: 0.9, 1.3, 0.9, 1.3, 0.9, 1.3, 0.9, 1.3, 0.9, 1.3, 0.9, 1.3, 0.9, 1.3, 0.9, 1.3, 0.9, 1.3
Intensity: 0.65, Timings: 0.9, 1.6, 0.9, 1.6, 0.9, 1.6, 0.9, 1.6, 0.9, 1.6, 0.9, 1.6, 0.9, 1.6, 0.9, 1.6
Intensity: 0.70, Timings: 0.9, 2.0, 0.9, 2.0, 0.9, 2.0, 0.9, 2.0, 0.9, 2.0, 0.9, 2.0, 0.9, 2.0
Intensity: 0.75, Timings: 0.8, 2.5, 0.8, 2.5, 0.8, 2.5, 0.8, 2.5, 0.8, 2.5, 0.8, 2.5
Intensity: 0.80, Timings: 0.8, 3.2, 0.8, 3.2, 0.8, 3.2, 0.8, 3.2, 0.8, 3.2
Intensity: 0.85, Timings: 0.8, 4.2, 0.8, 4.2, 0.8, 4.2, 0.8, 4.2
Intensity: 0.90, Timings: 0.7, 6.0, 0.7, 6.0, 0.7, 6.0
Intensity: 0.95, Timings: 0.5, 9.5, 0.5, 9.5
Intensity: 1.00, Timings: 0.0, 20.0
Run Code Online (Sandbox Code Playgroud)
这是伪劣的代码:
public void Test()
{
foreach (var intensity in Enumerable.Range(0, 20 + 1).Select(i => i/20f))
{
var cycle = new List<float> {a(intensity), b(intensity)};
var timings = Enumerable.Repeat(cycle, k(intensity)).SelectMany(timing => timing).ToArray();
SDebug.WriteLine(
String.Format("Intensity: {0,2:N2}, Timings: ", intensity) +
String.Join(", ", timings.Select(timing => String.Format("{0,2:N1}", timing))));
}
}
private static float r(float i)
{
return 1f/(1.000001f - i) - 1f;
}
private static int k(float i)
{
return Mathf.CeilToInt(10 - 18*Mathf.Abs(i - 0.5f));
}
private static float a(float i)
{
return 20/(k(i)*(1 + r(i)));
}
private static float b(float i)
{
return r(i)*a(i);
}
Run Code Online (Sandbox Code Playgroud)
从这里做的最好的事情是功能混乱r(i).如果你虽然可以,先放松,第一个和最后时刻是[n, 1]和[1, n],which'll从具有渐近打扰救你.
| 归档时间: |
|
| 查看次数: |
4409 次 |
| 最近记录: |