android - 将值从 Sensor.TYPE ORIENTATION 转换为欧拉角?

标签 android orientation rotation cube euler-angles

我必须在 Android 中编写一个指南针应用程序。用户在屏幕上看到的唯一东西是一个带有红色墙壁的立方体,该立方体必须指向北方。这并不重要。重要的是,我需要根据设备本身的旋转来旋转该立方体,以便无论手机如何握持,红墙都继续指向北。我的代码简单明了:

@Override
public void onSensorChanged(SensorEvent event) {
    synchronized (this) {
        switch (event.sensor.getType()){
        case Sensor.TYPE_ACCELEROMETER:
            direction = event.values[2];
            break;
        case Sensor.TYPE_ORIENTATION:
            if (direction < 0) {
                angleX = event.values[1];
                angleY = -event.values[2];
                angleZ = event.values[0];
            } else {
                angleX = -event.values[1];
                angleY = -event.values[2];
                angleZ = event.values[0];   
            }
            break;
        }
    }
}

我添加了这个额外的方向变量,它仅存储手机显示屏是朝下还是朝上。我不知道我是否需要它,但它似乎修复了一些错误。我正在使用SensorSimulator对于 android,但每当我的音调 slider 进入 [-90, 90] 区间时,其他变量就会混合在一起。就好像他们得到了 180 度的偏移。但我无法检测到我何时处于该区间,因为音高范围是从 -90 到 90,因此我可以从左侧移动 slider 进行书写,并且我将始终处于该区间。

这只是为了向您展示我的代码已经进步了多少。我并不是说这个问题应该如何解决,因为我可能只会把自己带入死胡同。你看,我已经尝试编写这个应用程序三天了,你可以想象我的老板有多生气。我已经阅读了各种教程并尝试了我能找到或想到的每个公式。所以请帮助我。我所要做的就是知道如何旋转我的立方体,其旋转角度是以度为单位的欧拉角。

最佳答案

这是我编写的一些代码,用于执行非常类似的操作,实际上只关心设备在滚动方向上的旋转。希望能帮助到你!它仅使用加速度计值来确定俯仰角,无需获取 View 的方向。

public void onSensorChanged(SensorEvent event) {
    float x = -1 * event.values[0] / SensorManager.GRAVITY_EARTH;
    float y = -1 * event.values[1] / SensorManager.GRAVITY_EARTH;
    float z = -1 * event.values[2] / SensorManager.GRAVITY_EARTH;

    float signedRawRoll = (float) (Math.atan2(x, y) * 180 / Math.PI);
    float unsignedRawRoll = Math.abs(signedRawRoll);
    float rollSign = signedRawRoll / unsignedRawRoll;
    float rawPitch = Math.abs(z * 180);

    // Use a basic low-pass filter to only keep the gravity in the accelerometer values for the X and Y axes
    // adjust the filter weight based on pitch, as roll is harder to define as pitch approaches 180.
    float filterWeight = rawPitch > 165 ? 0.85f : 0.7f;
    float newUnsignedRoll = filterWeight * Math.abs(this.roll) + (1 - filterWeight) * unsignedRawRoll;
    this.roll = rollSign * newUnsignedRoll;
    if (Float.isInfinite(this.roll) || Float.isNaN(this.roll)) {
        this.roll = 0;
    }
    this.pitch = filterWeight * this.pitch + (1 - filterWeight) * rawPitch;
    for (IAngleListener listener : listeners) {
        listener.deviceRollAndPitch(this.roll, this.pitch);
    }
}

关于android - 将值从 Sensor.TYPE ORIENTATION 转换为欧拉角?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3839583/

相关文章:

android - 使用Retrofit将音频文件上传到Flask API

java - 找不到符号类 PoolingHttpClientConnectionManager

iphone - 如何在自定义 iPhone 应用程序中从垂直 View 旋转到水平 View

android - 如何在布局/绘图发生之前更改屏幕方向?

c++ - 在 C++ 中验证 3 位环绕旋转

ios6 - 文本更改时UILabel缩小

class - PYGAME - 使一个对象旋转到自动生成的对象

android - 如何执行默认短信应用程序?

android - Wifi 热点组播/广播

ios - UIVisualEffectView 在方向更改时错误地更改边界