Android, How can I rotate an arrow (image) around a fixed point?

匿名 (未验证) 提交于 2019-12-03 02:47:02

问题:

I have an arrow image that I want to rotate from 0 to 180 degree (like the needle in a meter.) One point of the arrow is fixed in middle and at bottom of the screen and head of arrow should move. Length of arrow is fix (it is image). Also I have two buttons and I want arrow to turn left when button left is touched and turn right when right button is touched.

What is the logic of this process?

回答1:

This is actually pretty simple if you are using a canvas to do your drawing(as you should in your case).

Given that you know the coordinates for the point around which the image should rotate, you can do it like this:

private void doDraw(Canvas canvas) { canvas.save(); float px = ...; float py = ...; canvas.rotate(degrees, px, py); arrow.draw(canvas); canvas.restore(); }

degrees will be a integer value that you increment/decrement when the user clicks the L or R buttons. canvas.rotate takes care of the rest!



回答2:

You have to work with probably animation using 3d rotation in android and try to also usong Matrix Rotation ...I have bitmap code for this.........

Bitmap bmp=BitmapFactory.decodeResource(getResources(), R.drawable.bar);                 Matrix mtx = new Matrix();   mtx.postRotate(180);   // rotating 180 degrees clockwise   Bitmap rotatedBMP = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth() ,bmp.getHeight() , mtx, true);  // creating the bitmap image with new angle

also check this

http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/animation/Rotate3dAnimation.html



回答3:

So there is the short answer and the long answer.

The short answer is that rotation of bitmaps and canvasses is a common function, usually called "rotate" and usually taking the point around which to rotate.

The longer answer is that all 2D and 3D graphics devolve into a trick of matrix algebra. For each point: new_x = factor_1 * old_x + factor_2 * old_y + factor_3 ...

These factors work really nicely in a matrix, and is why the matrix thing got so popular. There is a cool trick where you chain the transformations together, so you might state your problems as "take the old canvas, move it so that the touched point is the origin, rotate it, and then move it so that the origin is back at the touched point." Or Matrix m = new Matrix().postTranslate(-touch_x, -touch_y).postRotate(360/20).postTranslate(touch_x, touch_y) to rotate it by 1/20th of circle each time. Then you pass the matrix to any function that takes the "transformation" matrix.

The cool thing is that you do all the calculations for that matrix just once, and then use the same 4 multiplications on each point and a bunch of adding. In fact, this is so common that video cards and the Intel instruction set both do this stuff in hardware. You can also just multiply the resulting image again by the same matrix to get the next one.

Now, if you are really asking for the graphics hack of how do I do this in some insanely fast assembly code with no memory, the trick is to pick rotations and errors into little chains where you don't need a buffer. For example, a simple 90 degree rotation would first swap the four corners, then it would swap (upper left + 1 left goes into upper right + 1 down which goes into lower right - 1 left which goes into lower left - 1 down, which goes back into the upper left + 1). These tricks usually only matter for memory constraints.

Way too much information. Tell us more about your problem.



回答4:

ImageView arrow = findViewById(/* id of your arrow */); int width = arrow.getWidth(); int height = arrow.getHeight(); newAngle = /* init it by needed angle */; RotateAnimation animation = new RotateAnimation(oldAngle, newAngle, width / 2, height); oldAngle = newAngle; animation.setDuration(200); // you may  set another duration animation.setFillAfter(true); arrow.startAnimation(animation);

Good luck!



回答5:

i see this example and i adapted to work more or less like you need, please see the example for a better understanding of my code :)


import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.os.Bundle; import android.widget.ImageView; import android.widget.SeekBar;  public class TesteRotateActivity extends Activity implements     SeekBar.OnSeekBarChangeListener {  private ImageView myImageView; private SeekBar seekbarRotate; private float curScale = 1F; private float curRotate = 0F; private Bitmap bitmap; private int bmpHeight;  /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     setContentView(R.layout.main);     myImageView = (ImageView) findViewById(R.id.imageview);     seekbarRotate = (SeekBar) findViewById(R.id.rotate);     bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.teste);//here you insert your image     bmpHeight = bitmap.getHeight();     drawMatrix();     seekbarRotate.setOnSeekBarChangeListener(this); }  private void drawMatrix() {     Matrix matrix = new Matrix();     Matrix matrixb = new Matrix();     Matrix matrixc = new Matrix();     matrix.postScale(curScale, curScale);     matrixb.setRotate(curRotate, 100, bmpHeight);     matrixc.setTranslate(100, 0);     matrix.setConcat(matrixb, matrixc);     Bitmap targetBitmap = Bitmap.createBitmap(200, bmpHeight,             bitmap.getConfig());     Canvas canvas = new Canvas(targetBitmap);     canvas.drawBitmap(bitmap, matrix, new Paint());     myImageView.setImageBitmap(targetBitmap); }  @Override public void onProgressChanged(SeekBar seekBar, int progress,         boolean fromUser) {     curRotate = (float) progress;     drawMatrix(); }  @Override public void onStartTrackingTouch(SeekBar seekBar) { }  @Override public void onStopTrackingTouch(SeekBar seekBar) { }  }

the xml of main

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" >  <TextView     android:layout_width="fill_parent"     android:layout_height="wrap_content"     android:text="@string/app_name" />  <SeekBar     android:id="@+id/rotate"     android:layout_width="fill_parent"     android:layout_height="wrap_content"     android:layout_margin="5px"     android:max="360"     android:progress="0" />  <ImageView     android:id="@+id/imageview"     android:layout_width="wrap_content"     android:layout_height="wrap_content"     android:layout_gravity="center"     android:scaleType="center" />  </LinearLayout>


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!