【问题标题】:Convert values form Sensor.TYPE_ORIENTATION to Euler angles?将 Sensor.TYPE ORIENTATION 的值转换为欧拉角?
【发布时间】:2010-10-01 13:26:36
【问题描述】:

我必须在 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;
        }
    }
}

我添加了这个额外的方向变量,它只存储手机的显示屏是向下还是向上。我不知道我是否需要它,但它似乎修复了一些错误。我正在为 android 使用SensorSimulator,但每当我的音高滑块进入 [-90, 90] 区间时,其他变量就会混淆。就好像他们得到了 180 的偏移量。但是我无法检测到我什么时候在这个区间,因为音高的范围是从 -90 到 90,所以我可以从左边移动那个滑块来写,我会一直在那个区间。

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

【问题讨论】:

    标签: android orientation rotation cube euler-angles


    【解决方案1】:

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

    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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-01
      • 2020-03-18
      • 2010-12-06
      • 1970-01-01
      相关资源
      最近更新 更多