java - 在Android中生成强度范围内的振动模式的算法?

标签 java android algorithm android-vibration

我正在尝试以编程方式生成开启和关闭“微脉冲”的 Android 振动模式,以控制最终用户感受到的振动强度。这是我在一些类似主题中推荐的解决方案,用于解决 API 未提供用于控制振动强度的接口(interface)的问题(据我所知,由于硬件的功能)。

然而,生成这些模式的算法似乎只是暗示,而没有发布实际算法。

我想做的是,给定一个介于 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]

对编写此类算法有任何帮助(或对实现相同目标的更好策略的建议)吗?

编辑:我添加了 100 声望的赏金:)

最佳答案

在研究这个问题一段时间后,由于数学天赋不高,我想出了一个过于简化的算法(与 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;
}

关于java - 在Android中生成强度范围内的振动模式的算法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20808479/

相关文章:

java - 当使用 JSch 通过 Java 执行时,某些 Unix 命令会失败并返回 "... not found"

android - Dagger 看不到我自己生成的依赖

java - actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS) 产生 NullPointerException

c# - 尝试实现 Speck32/64 分组密码

c - 将 X 转换为 Y 的步骤数。(整数)

java - 具有代码覆盖率的 REST API 集成测试

java - Jackson Spring Controller 序列化

android - child Android 的 ExpandableListView 动画

Java文本分割算法

java - 使用模板或泛型动态命名函数