在下面你会看到我的传感器管理器类..我用虚拟罗盘很好地工作,但点击我试图获得根据谷歌文档应该返回的方位角值 0=North, 90=east, 180 = south , 和 270 = 西...
我的应用程序仅设置为横向模式..
有趣的是,如果
我的手机在 PORTRAIT 中我得到:北 90,东 180,南 -90,西 0
如果我在横向模式下持有它:北 -40 到 -60 东约 30 东 -12 南 -156 西
相同的代码正在旋转一个可见的矩阵openGl指南针,这就是我将数字与磁力计实际认为的磁北进行比较的方式..我很困惑..有人请哦,请帮忙。
我的传感器类:
public void start(Context context,final int displayOrientation) {
listener = new SensorEventListener() {
private int displayOri = displayOrientation;
public void onAccuracyChanged(Sensor arg0, int arg1){}
public void onSensorChanged(SensorEvent evt) {
int type=evt.sensor.getType();
if (type == Sensor.TYPE_MAGNETIC_FIELD) {
orientation[0]=(orientation[0]*1+evt.values[0])*0.5f;
orientation[1]=(orientation[1]*1+evt.values[1])*0.5f;
orientation[2]=(orientation[2]*1+evt.values[2])*0.5f;
} else if (type == Sensor.TYPE_ACCELEROMETER) {
acceleration[0]=(acceleration[0]*2+evt.values[0])*0.33334f;
acceleration[1]=(acceleration[1]*2+evt.values[1])*0.33334f;
acceleration[2]=(acceleration[2]*2+evt.values[2])*0.33334f;
}
if ((type==Sensor.TYPE_MAGNETIC_FIELD) || (type==Sensor.TYPE_ACCELEROMETER)) {
float newMat[]=new float[16];
//Toast toast = Toast.makeText(ctx.getApplicationContext(), "accel", Toast.LENGTH_SHORT);
//toast.show();
SensorManager.getRotationMatrix(newMat, null, acceleration, orientation);
if(displayOri==0||displayOri==2){
SensorManager.remapCoordinateSystem(newMat,SensorManager.AXIS_X*-1, SensorManager.AXIS_MINUS_Y*-1,newMat);
}else{
SensorManager.remapCoordinateSystem(newMat,SensorManager.AXIS_Y, SensorManager.AXIS_MINUS_X,newMat);
}
matrix=newMat;
SensorManager.getOrientation (newMat, orientationValues);
}
}
};
sensorMan = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
sensorAcce = sensorMan.getSensorList(Sensor.TYPE_ACCELEROMETER).get(0);
sensorMagn = sensorMan.getSensorList(Sensor.TYPE_MAGNETIC_FIELD).get(0);
//sensorOri = sensorMan.getSensorList(Sensor.TYPE_ORIENTATION).get(0);
sensorMan.registerListener(listener, sensorAcce, SensorManager.SENSOR_DELAY_UI);
sensorMan.registerListener(listener, sensorMagn, SensorManager.SENSOR_DELAY_UI);
//sensorMan.registerListener(listener, sensorOri, SensorManager.SENSOR_DELAY_UI);
}
public float[] getMatrix() {
return matrix;
}
public float getRoll(){
return roll;
}
public float[] getACC(){
return acceleration;
}
public float[] getORI(){
return orientationValues;
}
public float getIncline(){
return sensorMan.getInclination(matrix);
}
public void finish() {
sensorMan.unregisterListener(listener);
}
public void onPause() {
sensorMan.unregisterListener(listener);
}
public void onResume(){
sensorMan.registerListener(listener, sensorAcce, SensorManager.SENSOR_DELAY_UI);
sensorMan.registerListener(listener, sensorMagn, SensorManager.SENSOR_DELAY_UI);
//sensorMan.registerListener(listener, sensorOri, SensorManager.SENSOR_DELAY_UI);
}
}
谷歌文档:
* SENSOR_ORIENTATION、SENSOR_ORIENTATION_RAW:所有值都是以度为单位的角度。values[0]: 方位角,绕 Z 轴旋转 (0<=azimuth<360)。0 = 北,90 = 东,180 = 南,270 = 西 值[1]:俯仰,绕 X 轴旋转 (-180<=pitch<=180),当 z 轴向 y- 移动时为正值轴。values[2]:滚动,绕 Y 轴旋转(-90<=roll<=90),当 z 轴向 x 轴移动时为正值。请注意,偏航、俯仰和横滚的定义不同于航空中使用的传统定义,其中 X 轴沿着飞机的长边(机尾到机头)。注意我现在没有使用sensor.orientation,因为它说我现在使用的方法更准确*
我还包括 openGL 类,该类使用相同的传感器数据创建一个准确的指南针,并带有一个名为 newTAg 的长按功能,它将传感器数据扔给我。
吐司看起来像这样:
Toast.makeText(getContext(), "INLCINE:"+phoneOri.getIncline()+" azimuth:"+Math.toDegrees(tagOri[0])+" pitch:"+Math.toDegrees(tagOri[1])+" roll:"+Math.toDegrees(tagOri[2]),Toast.LENGTH_LONG).show();
public GLLayer(Context context, int orientation) {
super(context);
this.context = context;
//this.square = new Square();
this.cRing = new Circle();
this.cNeedle = new CompassNeedle();
this.mNorth = new MarkerNorth();
this.mEast = new MarkerEast();
this.mSouth = new MarkerSouth();
this.mWest = new MarkerWest();
this.mSWest = new MarkerSouthWest();
this.mSEast = new MarkerSouthEast();
this.mNWest = new MarkerNorthWest();
this.mNEast = new MarkerNorthEast();
this.mtag = new tagImage();
phoneOri=new PhoneOrientation(context); // sensor manager and interpreter
// settings for translucent glView
this.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
this.getHolder().setFormat(PixelFormat.TRANSLUCENT);
// set render to inline
this.setRenderer(this);
phoneOri.start(context, orientation);
}
@Override
public void onDrawFrame(GL10 gl) {
gl.glEnable(GL10.GL_TEXTURE_2D);
// clear Screen and Depth Buffer
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// Reset the Modelview Matrix
gl.glLoadIdentity();
//GLU.gluLookAt(gl, eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
GLU.gluLookAt(gl,0, 0, 0, 0, 0, 0, 0, 0, 0);
//GLU.gluLookAt(gl, 90.0f, 1.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0, 1.0f, 0);
float floatMat[]=phoneOri.getMatrix();
gl.glMatrixMode(GL10.GL_MODELVIEW);
//
//gl.glTranslatef(0,0,-200.0f);
//cRing.draw(gl);
//DrawCompass Needle and Markers
gl.glLoadMatrixf(floatMat, 0);
for(int i=0;i<tags.size();i++){
gl.glPushMatrix();
//GLU.gluLookAt(gl,0, 0, 0, 0, 0, 0, 0, 0, 0);
//float angle = phoneOri.sensorMan,getAngleChange();
gl.glRotatef(90,2, 0,0);
mtag.draw(gl);
gl.glLoadMatrixf(floatMat,0);
}
gl.glPushMatrix();
gl.glTranslatef(0,0,-10.0f);
cNeedle.draw(gl);
gl.glLoadMatrixf(floatMat,0);
//Draw compass ring
//gl.glPushMatrix();
gl.glTranslatef(0,0,10.0f);
cRing.draw(gl);
//Draw South
gl.glTranslatef(0.0f,-150.0f,-10.0f);
mSouth.draw(gl);
//Draw West
gl.glTranslatef(-150.0f,150.0f,0.0f);
mWest.draw(gl);
//DrawNorth
gl.glTranslatef(150.0f,150.0f,0.0f);
mNorth.draw(gl);
//DrawEast
gl.glTranslatef(150.0f,-150.0f,0.0f);
mEast.draw(gl);
//SW
gl.glTranslatef(-225.0f, -75.0f, 0.0f);
mSWest.draw(gl);
// NW
gl.glTranslatef(0.0f,150.f,0);
mNWest.draw(gl);
gl.glTranslatef(150.0f, 0f, 0f);
mNEast.draw(gl);
gl.glTranslatef(0.0f,-150.0f,0.0f);
mSEast.draw(gl);
// Drawing
//gl.glNormal3f(0,0,1);
//gl.glTranslatef(0.0f,-150.0f,0.0f); // move 5 units INTO the screen
//square.draw(gl); // Draw the square
gl.glPushMatrix();
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
if(height == 0) { //Prevent A Divide By Zero By
height = 1; //Making Height Equal One
}
float ratio = (float) width / height;
gl.glViewport(0, 0, width, height); //Reset The Current Viewport
gl.glMatrixMode(GL10.GL_PROJECTION); //Select The Projection Matrix
gl.glLoadIdentity(); //Reset The Projection Matrix
//Calculate The Aspect Ratio Of The Window
//gl.glFrustumf(-ratio, ratio, -1, 1, 1, 100);
GLU.gluPerspective(gl, 35.0f, (float)width / (float)height, 5.0f, 200.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW); //Select The Modelview Matrix
gl.glLoadIdentity(); //Reset The Modelview Matrix
GLU.gluLookAt(gl, 0, 1.0f, 5.0f, 0, 0, 0, 0, 1.0f, 0);
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig arg1) {
// Load the texture for the square
//square.loadGLTexture(gl, this.context);
cRing.loadGLTexture(gl, this.context);
cNeedle.loadGLTexture(gl, this.context);
mNorth.loadGLTexture(gl, this.context);
mEast.loadGLTexture(gl, this.context);
mSouth.loadGLTexture(gl, this.context);
mWest.loadGLTexture(gl, this.context);
mSWest.loadGLTexture(gl, this.context);
mNWest.loadGLTexture(gl, this.context);
mSEast.loadGLTexture(gl, this.context);
mNEast.loadGLTexture(gl, this.context);
gl.glEnable(GL10.GL_TEXTURE_2D); //Enable Texture Mapping ( NEW )
gl.glShadeModel(GL10.GL_SMOOTH); //Enable Smooth Shading
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); //Black Background
gl.glClearDepthf(1.0f); //Depth Buffer Setup
gl.glEnable(GL10.GL_DEPTH_TEST); //Enables Depth Testing
gl.glDepthFunc(GL10.GL_LEQUAL); //The Type Of Depth Testing To Do
//Really Nice Perspective Calculations
//gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_SMOOTH);
}
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
// TODO Auto-generated method stub
}
public void newTag(){
float tagOri[] = new float[3];
tagOri = phoneOri.getORI();
tags.add(phoneOri.getMatrix());
Toast.makeText(getContext(), "INLCINE:"+phoneOri.getIncline()+" azimuth:"+Math.toDegrees(tagOri[0])+" pitch:"+Math.toDegrees(tagOri[1])+" roll:"+Math.toDegrees(tagOri[2]),Toast.LENGTH_LONG).show();
}
}