我必须在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,但每当我的音调滑块进入[-90,90]区间时,其他变量就会混淆。这就像他们得到180偏移。但我无法检测到我在这段时间内是因为音高的范围是从-90到90,所以我可以将该滑块从左移动到写入,我将始终处于该间隔内。
这只是为了向您展示我的代码有多远。我不是说这个问题应该如何解决,因为我只会让自己陷入死胡同。你看,我一直试着写这个应用程序3天了,你可以想象我的老板是多么生气。我已经阅读了各种各样的教程,并尝试了我能找到或想到的每一个公式。所以请帮助我。我所要做的就是知道如何旋转我的立方体,其旋转角度是以度为单位的EULER ANGLES。
答案 0 :(得分:3)
这是我编写的一些代码,用来做一些非常相似的事情,实际上只关心设备在滚动方向上的旋转。希望能帮助到你!它只是使用加速度计值来确定音高,而不需要获得视图的方向。
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);
}
}