我正在开发基于实时位置的增强现实Android应用程序。 这是一个简单的概念:我的应用程序应该显示我周围的一些地方。我有 对此进行了深入的研究,但我仍然遇到了问题。我有我的GPS坐标 和目标地点的GPS坐标。
我的问题是:如何检索手机的相机正在查看的内容(例如建筑物)? 解决这样的问题的逻辑方法是什么?
答案 0 :(得分:5)
增强现实将实际坐标系统转移到摄像机坐标系统。在基于AR位置中,实际坐标是地理坐标系。我们将GPS坐标(纬度,经度,海拔高度)转换为导航坐标(东,北,上),然后将导航坐标转换为摄像机坐标,并将其显示在摄像机视图上。
我只是为您创建演示: https://github.com/dat-ng/ar-location-based-android
答案 1 :(得分:2)
首先检查设备中传感器的可用性。如果设备支持TYPE_ROTATION_VECTOR,则为其注册传感器侦听器,或者检查TYPE_MAGNETIC_FIELD和TYPE_ACCELEROMETER。
SensorManager mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
rSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
if (rSensor == null) {
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
aSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
}
然后在onSensorChanged函数中,你应该计算方位角。
if (rSensor == null) {
switch (event.sensor.getType()) {
case Sensor.TYPE_MAGNETIC_FIELD:
magnetic = event.values.clone();
break;
case Sensor.TYPE_ACCELEROMETER:
accelerometer = event.values.clone();
break;
}
if (magnetic != null && accelerometer != null) {
Rot = new float[9];
I = new float[9];
SensorManager.getRotationMatrix(Rot, I, accelerometer, magnetic);
float[] outR = new float[9];
SensorManager.remapCoordinateSystem(Rot, SensorManager.AXIS_X,
SensorManager.AXIS_Z, outR);
SensorManager.getOrientation(outR, values);
azimuth = values[0];
magnetic = null;
accelerometer = null;
}
} else {
SensorManager.getRotationMatrixFromVector(mRotationMatrix, event.values);
SensorManager.getOrientation(mRotationMatrix, mValues);
azimuth = Math.toDegrees(mValues[0]));
}
}
您可以使用此方位角在cameraview中绘制位置
double angle = bearing(myLatitude, myLongitude, dLatitude, dLongitude) - azimuth;
double xAxis, yAxis;
if(angle < 0)
angle = (angle+360)%360;
xAxis = Math.sin(Math.toRadians(angle)) * dist;
yAxis = Math.sqrt(Math.pow(dist, 2) - Math.pow(xAxis, 2));
if (angle > 90 && angle < 270)
yAxis *= -1;
double xAxisPosition = angle * (screenWidth / 90d);
xAxis = xAxisPosition - spotImageWidth/2;
float x, y;
if (angle <= 45)
x = (float) ((screenWidth / 2) + xAxis);
else if (angle >= 315)
x = (float) ((screenWidth / 2) - ((screenWidth*4) - xAxis));
else
x = (float) (float)(screenWidth*9);
y = (float)(((screenHeight - 300) - (i * 100)));
protected static double bearing(double lat1, double lon1, double lat2, double lon2) {
double longDiff = Math.toRadians(lon2 - lon1);
double la1 = Math.toRadians(lat1);
double la2 = Math.toRadians(lat2);
double y = Math.sin(longDiff) * Math.cos(la2);
double x = Math.cos(la1) * Math.sin(la2) - Math.sin(la1) * Math.cos(la2) * Math.cos(longDiff);
double result = Math.toDegrees(Math.atan2(y, x));
return (result+360.0d)%360.0d;
}
x,y将给出目的地位置的坐标。
答案 2 :(得分:0)
您需要的第一步是使用传感器来获取后置摄像头的方向。您可以在http://developer.android.com/reference/android/hardware/SensorManager.html了解有关传感器的更多信息 完成传感器编码后回来询问下一个问题。
答案 3 :(得分:0)
试用DroidAR SDK https://github.com/bitstars/droidar。这是适用于Android的AR SDK。你应该用它来解决你的大多数问题。还有视频手册。如果您只需要项目的一些东西,也可以查看代码。
答案 4 :(得分:0)
此问题有两个方向,即设备和目标。
设备位置的方位角如下所示:
此信息可由传感器收集。但是,如果设备的方向未修复,则应执行SensorManager.remapCoordinateSystem
目标的方位角如下所示:
这可能是我在网上找到的最好的人物。 一旦有了设备位置,目标位置就可以通过以下方式计算:
azi = Math.abs(Math.toDegrees(Math.atan((tlon-lon)/(tlat-lat))));
其中tlat
和tlon
表示目标gps位置,lat和lon是设备位置。
这个等式的值在-90到+90之间,这不是方位角的真实含义。因此,应该添加3个额外的代码。
if((tlon-lon)>0&&(tlat-lat)<0){
azi = 180 - azi;
}
if((tlon-lon)<0&&(tlat-lat)<0){
azi = 180 + azi;
}
if((tlon-lon)<0&&(tlat-lat)>0){
azi = 360 - azi;
}
完成这些操作后,只需轻松检测目标是否在您眼前。
希望这些有所帮助。