Android 将Sensor.TYPE_方向的值转换为Euler角度?

Android 将Sensor.TYPE_方向的值转换为Euler角度?,android,orientation,rotation,cube,euler-angles,Android,Orientation,Rotation,Cube,Euler Angles,我必须用Android编写一个指南针应用程序。用户在屏幕上看到的唯一东西是一个红色的立方体,它必须指向北方。这并不重要。重要的是,我需要根据设备本身的旋转来旋转立方体,这样无论手机如何手持,红墙都会继续指向北方。我的代码简单明了: @Override public void onSensorChanged(SensorEvent event) { synchronized (this) { switch (event.sensor.getType()){

我必须用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;
        }
    }
}
@覆盖
传感器更改时的公共无效(传感器事件){
已同步(此){
开关(event.sensor.getType()){
外壳传感器.U型加速计:
方向=事件值[2];
打破
外壳传感器。类型_方向:
如果(方向<0){
angleX=事件值[1];
angleY=-event.values[2];
angleZ=事件值[0];
}否则{
angleX=-event.values[1];
angleY=-event.values[2];
angleZ=事件值[0];
}
打破
}
}
}
我添加了这个额外的方向变量,它只存储手机的显示是向下还是向上。我不知道我是否需要它,但它似乎修复了一些错误。我正在使用android的,但每当我的音高滑块在[-90,90]间隔内移动时,其他变量就会混淆。就好像他们得到了180度的偏移。但我无法检测何时处于这个间隔,因为音高的范围是从-90到90,所以我可以将滑块从左侧移动到写入,我将始终处于该间隔


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

以下是我编写的一些代码,用于做一些非常类似的事情,实际上只关心设备在滚动方向上的旋转。希望有帮助!它只使用加速计值来确定俯仰,不需要获得视图的方向

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