下面你會看到我的傳感器管理員類..我有一個虛擬羅盤工作很好,但點擊我想獲得方位角值,根據谷歌文檔應該返回0 =北,90 =東,180 =南,270 =西...方位角錯誤的值
我的應用程序設置爲僅橫向模式..
有趣的是,如果
我的手機在肖像舉行我得到: 90爲北, 180爲東, -90爲南, 0爲西
,如果我拿在lanscape模式: -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 < =方位角< 360)。 0 =北,90 =東,180 =南,270 =西 值[1]:繞X軸旋轉的間距(-180,< =間距< = 180),當z軸移向y時-軸。 values [2]:滾動,圍繞Y軸旋轉(-90 < = roll < = 90),當z軸向x軸移動時爲正值。 請注意,偏航,俯仰和滾轉的定義不同於X軸沿飛機長邊(尾到鼻)的航空中使用的傳統定義。 注意到我沒有使用sensor.orientation現在,因爲它說現在使用的方法IM是更準確*
我還包括創建使用相同的傳感器數據與所謂的長按功能準確的指南針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();
}
}