gpt4 book ai didi

android - 像指南针一样旋转 ImageView(在别处设置 "north pole")

转载 作者:IT老高 更新时间:2023-10-28 21:40:35 26 4
gpt4 key购买 nike

我对如何实现“个人指南针”感到困惑,即指向特定方位而不是标准“北极”的指南针......不幸的是,我目前的尝试出现了错误(不是指向给定的方位角)。它还与加速器连接,能够根据用户转动的方式动态调整自身。

这是我目前的尝试(更新箭头的 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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com