Reputation: 53600
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?
Upvotes: 8
Views: 11226
Reputation: 14505
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>
Upvotes: 0
Reputation: 20510
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.
Upvotes: 2
Reputation: 1931
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!
Upvotes: 1
Reputation: 3911
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!
Upvotes: 5
Reputation: 40416
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
Upvotes: 2