Rotate icons/views along a circular path, on scroll - Android - android

I'm basically trying to implement something similar to this. Sadly, it's an iOS tutorial.
I have googled in most possible keywords to move something in circular manner, but couldn't find any to start off. Can any one atleast provide any hints on how this can be hacked on android? Please.
Thanks.

i used rotate animation to rotate an image about a point.
double r = Math.atan2(evt.getX() - turntable.getWidth() / 2, turntable.getHeight() / 2 - evt.getY());
rotation = (int) Math.toDegrees(r);
if (evt.getAction() == MotionEvent.ACTION_MOVE)
{
x= (int)evt.getX();
y = (int)evt.getY();
rotateAnim = new RotateAnimation(angle,rotation-50,200,100);
rotateAnim.setFillAfter(true);
ImageView.setanimation(rotateAnim );
ImageView.startAnimation(rotateAnim);
}
you can also use matrix
float newRot = new Float(rot);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.disc);
Matrix matrix = new Matrix();
matrix.postRotate(newRot - 50);
Bitmap redrawnBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
turntable.setImageBitmap(redrawnBitmap);

This would be pretty easy to do in a custom control. Just create a class that extends View and override the draw() method. Then you can listen for touches and calculate how far the user has rotated the control. Then you just need to use that data to rotate the canvas and draw the numbers on it.
-= Update =-
When you override the draw method you get a Canvas object. That object lets you draw to it what ever you want. It would look something like this:
#Override
public void draw(Canvas c)
{
c.rotate(amount);
c.drawBitmap(myImage);
}
This is a link to the full Canvas Documentation.

Related

Convert Android Matrix values to View transform properties

I have a View which is rotated around the X and Y axis using View.setRotationX and View.setRotationY. I have used View.getMatrix() and modified the values of the Matrix. I would now like to apply the Matrix back to the View but I have not found a good way of doing this without using the legacy Animation API in Android.
Basically what i need is to convert the Matrix values to View transformation values.
Example:
float[] src = new float[]{0, 0, view.getWidth(), 0, 0, view.getHeight(), view.getWidth(), view.getHeight()};
float[] dst = new float[8];
Matrix matrix = view.getMatrix();
matrix.mapPoints(dst, src);
dst[7] = NEW_Y_COORD_OF_CORNER;
matrix.setPolyToPoly(src, 0, dst, 0, dst.length >> 1);
//The matrix is now changed but the View is not.
So i would like to get rotation and translation of the Matrix to apply it back to the View:
float newRotationX = convertMatrixRotationToViewRotationX(matrix); //method i need
float newRotationY = convertMatrixRotationToViewRotationY(matrix); //method i need
float newTranslationX = convertMatrixRotationToViewTranslationX(matrix); //method i need
float newTranslationY = convertMatrixRotationToViewTranslationY(matrix); //method i need
view.setRotationY(newRotationX);
view.setRotationX(newRotationY);
view.setX(newTranslationX);
view.setY(newTranslationY);
This might seem like a far to complex way of transforming the View but I need to do it this way in order to be able to set x,y corner coordinates of the View. For more info of getting the corner coordinates of a way see my previous post here: https://stackoverflow.com/questions/24330073/how-to-get-all-4-corner-coordinates-of-a-view-in-android?noredirect=1#comment37672700_24330073

Inverse drawing of Bitmap on Canvas

How can I inverse the image drawed into a Canvas?
I has the following:
canvas.save();
canvas.drawBitmap(image.current(), null, currentBounds(), Paints.BLANK);
canvas.restore();
How can I make the current image be drawed fliped on x-axis into the currentBounds()?
I already found some answers indicating usage of Matrix, but I wan't to know if there's a easier way? Such a Paint with some flag turned on.
EDIT:
Following is my try with Matrix transformations:
Rect currentBounds = currentBounds();
currentBounds.offset((int)offset.x(), (int)offset.y());
float scale = image.current().getWidth() / currentBounds.width();
Matrix matrix = new Matrix();
matrix.setScale(- scale - 1, scale + 1);
matrix.postTranslate(currentBounds.left, currentBounds.top);
canvas.drawBitmap(image.current(), matrix, Paints.BLANK);
canvas.drawRect(currentBounds, Paints.STROKE_BLUE);
The following is the result of this draw:
https://dl.dropbox.com/u/28683814/game.png
As can be seen, the sprite is being drawed from 0,0 to left and it's not fully completes the currentBounds(), what I'm doing wrong?
Use
canvas.scale(-1,0,width/2,height/2);
as mentioned by my own answer here.
Although, I would point out that it will take you about a minute to understand Matrices, and it'll make you a better Android programmer.
Use this. I think this is quite easy.
canvas.save();
canvas.rotate(180, x, y);
canvas.drawBitmap(bitmap, x, y, null);
canvas.restore();
Well, I solved this way:
Rect currentBounds = currentBounds();
currentBounds.offset((int)offset.x(), (int)offset.y());
float scale = (float) currentBounds.width() / (float) image.current().getWidth();
boolean leftMovement = movingLeft();
Matrix matrix = new Matrix();
matrix.setScale(leftMovement ? -scale : scale, scale);
matrix.postTranslate(leftMovement ? currentBounds.right : currentBounds.left, currentBounds.top);
canvas.drawBitmap(image.current(), matrix, Paints.BLANK);
But this "leftMovement ? currentBounds.right : currentBounds.left" does not looks right

Rotate 'something that can be drawn on Canvas'

Hi have a problem regarding rotation. I'm currently drawing a few Objects on a Canvas. Currently this 'Objects' are just Bitmaps. After computing the rotation and passing it inside a Matrix, I'm forced to create a new Bitmap to get it rotated. A small snippet will clearify this:
public void onDraw(Canvas canvas){
mMatrix = new Matrix();
mMatrix.postRotate(getRotation());
Bitmap rotateBmp = Bitmap.createBitmap(mBitmap, 0, 0, mBitmap.getWidth(), mBitmap.getHeight(), mMatrix, true);
canvas.drawBitmap(rotateBmp, mCoords.x -(mBitmap.getWidth() / 2), mCoords.y - ( mBitmap.getHeight() / 2), null);
rotateBmp.recycle();
}
All I can do to save memory is calling recycle on the rotateBmp, and it will run most of the time correctly. Lets assume I have 10 Bitmap 'Objects' I want to rotate. That means I have to keep ten Bitmaps as 'sample' and create ten new Bitmaps in every draw-cycle plus an additional new Matrix (didn't find a way to 'reset' it). This sounds very weird to me. Is there another Way, to create 'something that can be drawn on a Canvas' on the fly (no XML), while keeping control of their rotation. Any Idea is very welcome. If its a View, a Drawable or another CustomClass doesn't matter. Maybe it is important that getRotation will be all the same for every "Something" that should be drawn. What is the best practice to do that?
You can rotate the Canvas using canvas.rotate(float degrees)
public void onDraw(Canvas canvas) {
canvas.drawBitmap(mBitmap, mCoords.x -(mBitmap.getWidth() / 2), mCoords.y - ( mBitmap.getHeight() / 2), null);
canvas.rotate(getRotation());
}
With the great help of #Jason Robinson and how To Rotate Text in Canvas I figured out a Way, of how I can do it. Here is a short snippet, that will work:
Bitmap mBitmap = getResources()...
int xPositionOfBitmap
int yPositionOfBitmap
public void onDraw(Canvas canvas) {
int bitmapCenterX = xPositionOfBitmap + (mBitmap.getWidth() / 2)
int bitmapCenterY = yPositionOfBitmap + (mBitmap.getHeight() / 2)
canvas.save()
canvas.rotate(getRotation(),bitmapCenterX, bitmapCenterY)
canvas.drawBitmap(mBitmap, xPositionOfBitmap, yPositionOfBitmap)
canvas.restore()
}

Problem in rotating image in android

I am facing problme in rotating image
Following code works fine
Matrix matrix = new Matrix();
matrix.postRotate(DEGREE,mBitmap.getWidth() / 2, mBitmap.getHeight() / 2);
Bitmap m = Bitmap.createBitmap(mBitmap, 0, 0, mBitmap.getWidth(),mBitmap.getHeight(), matrix, true);
canvas.drawBitmap(m, mX, mY, null);
But I dont want to create a new bitmap again and again so I am using the following code
Matrix matrix = new Matrix();
matrix.postTranslate(mX, mY);
matrix.postRotate(DEGREE,mBitmap.getWidth() / 2, mBitmap.getHeight() / 2);
canvas.drawBitmap(mBitmap, matrix, null);
In that case image goes out of the view. It is not visible.
Matrix matrix = new Matrix();
canvas.translate(mX, mY);
canvas.drawBitmap(...);
canvas.translate(-mX, -mY);
Try first rotating it then translating it, because when you translate it first the center is not in the middle any more so you are rotating it with wrong pivot coordinates.
The pivot point by default when rotating is the top left corner of the image, which is why the view goes out of view. You need to add logic to make the pivot point the center of the image. Unfortunately, geometry is not my strong suit so maybe someone who somewhat enjoys geometry can give you the calculations to make this happen.

Rotating a bitmap on an axis in Android

I have a bitmap flush with the bottom of my screen. When the user clicks a button I want it to rotate to the right by one degree. I am able to accomplish this but the problem is that the bottom of the item is no longer flush with the screen. I need it to appear to rotate on its bottom axis. I could use some hack to increment the x and y when its rotated (using trial and error I suppose) but is there a formula or something more elegant I can use?
public void rotate(int degrees)
{
Matrix mat = new Matrix();
mat.postRotate(degrees);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), mat, true);
}
Could you not instead use the following method that Matrix also has:
postRotate (float degrees, float px, float py)
It enables rotation on the specified point.

Categories

Resources