- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我对如何实现“个人指南针”感到困惑,即指向特定方位而不是标准“北极”的指南针......不幸的是,我目前的尝试出现了错误(不是指向给定的方位角)。它还与加速器连接,能够根据用户转动的方式动态调整自身。
这是我目前的尝试(更新箭头的 onSensorChanged()
方法):
public void onSensorChanged( SensorEvent event ) {
// If we don't have a Location, we break out
if ( LocationObj == null ) return;
float azimuth = event.values[0];
float baseAzimuth = azimuth;
GeomagneticField geoField = new GeomagneticField( Double
.valueOf( LocationObj.getLatitude() ).floatValue(), Double
.valueOf( LocationObj.getLongitude() ).floatValue(),
Double.valueOf( LocationObj.getAltitude() ).floatValue(),
System.currentTimeMillis() );
azimuth += geoField.getDeclination(); // converts magnetic north into true north
//Correct the azimuth
azimuth = azimuth % 360;
//This is where we choose to point it
float direction = azimuth + LocationObj.bearingTo( destinationObj );
rotateImageView( arrow, R.drawable.arrow, direction );
//Set the field
if( baseAzimuth > 0 && baseAzimuth < 45 ) fieldBearing.setText("S");
else if( baseAzimuth >= 45 && baseAzimuth < 90 ) fieldBearing.setText("SW");
else if( baseAzimuth > 0 && baseAzimuth < 135 ) fieldBearing.setText("W");
else if( baseAzimuth > 0 && baseAzimuth < 180 ) fieldBearing.setText("NW");
else if( baseAzimuth > 0 && baseAzimuth < 225 ) fieldBearing.setText("N");
else if( baseAzimuth > 0 && baseAzimuth < 270 ) fieldBearing.setText("NE");
else if( baseAzimuth > 0 && baseAzimuth < 315 ) fieldBearing.setText("E");
else if( baseAzimuth > 0 && baseAzimuth < 360 ) fieldBearing.setText("SE");
else fieldBearing.setText("?");
}
这是旋转 ImageView 的方法(rotateImageView()
):
private void rotateImageView( ImageView imageView, int drawable, float rotate ) {
// Decode the drawable into a bitmap
Bitmap bitmapOrg = BitmapFactory.decodeResource( getResources(),
drawable );
// Get the width/height of the drawable
DisplayMetrics dm = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(dm);
int width = bitmapOrg.getWidth(), height = bitmapOrg.getHeight();
// Initialize a new Matrix
Matrix matrix = new Matrix();
// Decide on how much to rotate
rotate = rotate % 360;
// Actually rotate the image
matrix.postRotate( rotate, width, height );
// recreate the new Bitmap via a couple conditions
Bitmap rotatedBitmap = Bitmap.createBitmap( bitmapOrg, 0, 0, width, height, matrix, true );
//BitmapDrawable bmd = new BitmapDrawable( rotatedBitmap );
//imageView.setImageBitmap( rotatedBitmap );
imageView.setImageDrawable(new BitmapDrawable(getResources(), rotatedBitmap));
imageView.setScaleType( ScaleType.CENTER );
}
任何帮助将不胜感激,因为我不太知道如何进行。我在尝试时得到的“读数”有些不准确,并且指向错误的方向。我是在做一些真正的事情,还是我只是进行了一次非常糟糕的试运行?
最佳答案
您的 rotateImageView 函数应该可以正常工作,但是在您的旋转计算中需要更改一些内容。
//This is where we choose to point it
float direction = azimuth + LocationObj.bearingTo( destinationObj );
rotateImageView( arrow, R.drawable.arrow, direction );
问题是 BearingTo 会给你一个从 -180 到 180 的范围,这会让事情有点困惑。我们需要将此值转换为 0 到 360 的范围才能获得正确的旋转。
这是一张我们真正想要的表格,与bearingTo给我们的比较
+-----------+--------------+| bearingTo | Real bearing |+-----------+--------------+| 0 | 0 |+-----------+--------------+| 90 | 90 |+-----------+--------------+| 180 | 180 |+-----------+--------------+| -90 | 270 |+-----------+--------------+| -135 | 225 |+-----------+--------------+| -180 | 180 |+-----------+--------------+
Even though the bearingTo is in the range -180 to 180, 0 is still true north which will leave us to this calculation:
// Store the bearingTo in the bearTo variable
float bearTo = LocationObj.bearingTo( destinationObj );
// If the bearTo is smaller than 0, add 360 to get the rotation clockwise.
if (bearTo < 0) {
bearTo = bearTo + 360;
}
如果我们添加一些虚拟值来测试我们的新公式:
float bearTo = -100;
// This will now equal to true
if (-100 < 0) {
bearTo = -100 + 360 = 360 - 100 = 260;
}
我们现在已经解决了bearingTo,让我们继续前往方位角!
您需要减去偏角而不是相加,因为当我们将手机直接指向真北时,我们希望方位角为 0,而不是将偏角添加到方位角上,这样当我们将偏角加倍时将手机指向正北。通过减去偏角而不是添加偏角来纠正此问题。
azimuth -= geoField.getDeclination(); // converts magnetic north into true north
当我们现在将手机转向真北时,方位角将等于 0
您不再需要校正方位角的代码。
// Remove / uncomment this line
azimuth = azimuth % 360;
我们现在将继续计算实际旋转的位置。但首先我会总结一下我们现在拥有的值(value)观类型并解释它们的真正含义:
bearTo = 从我们当前所站的点,从真北到目标位置的角度。
azimuth = 您将手机从正北旋转的角度。
这样说,如果您将手机直接指向正北,我们真的希望箭头旋转 BearTo 设置的角度。如果您将手机指向正北 45 度,我们希望箭头比 BearTo 旋转 45 度。这让我们进行以下计算:
float direction = bearTo - azimuth;
但是,如果我们输入一些虚拟值: BearTo = 45; 方位角 = 180;
direction = 45 - 180 = -135;
这意味着箭头应该逆时针旋转 135 度。我们需要像使用 BearTo 一样放入一个类似的 if 条件!
// If the direction is smaller than 0, add 360 to get the rotation clockwise.
if (direction < 0) {
direction = direction + 360;
}
您的轴承文本,N、E、S 和 W 已关闭,因此我已在下面的 final方法中更正它们。
您的 onSensorChanged 方法应如下所示:
public void onSensorChanged( SensorEvent event ) {
// If we don't have a Location, we break out
if ( LocationObj == null ) return;
float azimuth = event.values[0];
float baseAzimuth = azimuth;
GeomagneticField geoField = new GeomagneticField( Double
.valueOf( LocationObj.getLatitude() ).floatValue(), Double
.valueOf( LocationObj.getLongitude() ).floatValue(),
Double.valueOf( LocationObj.getAltitude() ).floatValue(),
System.currentTimeMillis() );
azimuth -= geoField.getDeclination(); // converts magnetic north into true north
// Store the bearingTo in the bearTo variable
float bearTo = LocationObj.bearingTo( destinationObj );
// If the bearTo is smaller than 0, add 360 to get the rotation clockwise.
if (bearTo < 0) {
bearTo = bearTo + 360;
}
//This is where we choose to point it
float direction = bearTo - azimuth;
// If the direction is smaller than 0, add 360 to get the rotation clockwise.
if (direction < 0) {
direction = direction + 360;
}
rotateImageView( arrow, R.drawable.arrow, direction );
//Set the field
String bearingText = "N";
if ( (360 >= baseAzimuth && baseAzimuth >= 337.5) || (0 <= baseAzimuth && baseAzimuth <= 22.5) ) bearingText = "N";
else if (baseAzimuth > 22.5 && baseAzimuth < 67.5) bearingText = "NE";
else if (baseAzimuth >= 67.5 && baseAzimuth <= 112.5) bearingText = "E";
else if (baseAzimuth > 112.5 && baseAzimuth < 157.5) bearingText = "SE";
else if (baseAzimuth >= 157.5 && baseAzimuth <= 202.5) bearingText = "S";
else if (baseAzimuth > 202.5 && baseAzimuth < 247.5) bearingText = "SW";
else if (baseAzimuth >= 247.5 && baseAzimuth <= 292.5) bearingText = "W";
else if (baseAzimuth > 292.5 && baseAzimuth < 337.5) bearingText = "NW";
else bearingText = "?";
fieldBearing.setText(bearingText);
}
关于android - 像指南针一样旋转 ImageView(在别处设置 "north pole"),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7978618/
我对如何实现“个人指南针”感到困惑,即指向特定方位而不是标准“北极”的指南针......不幸的是,我目前的尝试出现了错误(不是指向给定的方位角)。它还与加速器连接,能够根据用户转动的方式动态调整自身。
我正在将推车和杆模拟与 python 3.7 和 Julia 1.2 进行比较。在 python 中,模拟被编写为如下所示的类对象,而在 Julia 中只是一个函数。使用 Julia 解决问题的时间是
我正在开发一个使用 PostgreSQL 作为数据库的应用程序;我的目标是以地理格式存档多边形数据,以便在进行查询时使用 pgAdmin OpenStreetMap 集成轻松可视化它们。我的问题是,当
我正在尝试在球体上构建六边形/测地线网格。出于我的目的,我只关注北极。到目前为止,我已经成功地使用 stripy 包构建了一个基于二十面体的三角形网格。 stripy 包允许我通过二分法细化网格:每条
我是一名优秀的程序员,十分优秀!