2011-09-14 55 views
8

Tôi có một hình ảnh mũi tên mà tôi muốn xoay từ 0 đến 180 độ (như kim trong một mét.) Một điểm của mũi tên được cố định ở giữa và ở dưới cùng của màn hình và đầu mũi tên sẽ di chuyển. Độ dài của mũi tên được sửa (nó là hình ảnh). Ngoài ra tôi có hai nút và tôi muốn mũi tên để rẽ trái khi nút trái được chạm vào và rẽ phải khi nút phải được chạm vào.Android, Làm thế nào tôi có thể xoay một mũi tên (hình ảnh) xung quanh một điểm cố định?

Logic của quá trình này là gì?

enter image description here

+0

Sử dụng ma trận để áp dụng xoay vòng. –

+1

Bản sao chính xác của http://stackoverflow.com/questions/4166917/android-how-to-rotate-a-bitmap-on-a-center-point – Ronnie

+0

tôi khuyên bạn sử dụng @Emiam câu trả lời, điều này sẽ không sử dụng CPU như Matrix làm. –

Trả lời

2

Bạn phải làm việc với lẽ hình ảnh động sử dụng xoay vòng 3d trong android và cố gắng cũng để usong Matrix Rotation ... Tôi có mã bitmap cho điều này .........

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 

cũng kiểm tra này

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

+0

Đây không phải là một chiến lược tốt bởi vì phương pháp Bitmap.createBitmap là rất chậm, và làm điều đó mỗi khung sẽ giết tỷ lệ FPS. – Emiam

5

Đây là thực sự khá đơn giản nếu bạn đang sử dụng một tấm vải để làm bản vẽ của bạn (như bạn nên trong trường hợp của bạn).

Cho rằng bạn biết được tọa độ cho các điểm xung quanh mà hình ảnh nên xoay, bạn có thể làm điều đó như thế này:

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

độ sẽ là một giá trị số nguyên mà bạn tăng/giảm khi người dùng nhấp vào Nút L hoặc R. canvas.rotate chăm sóc phần còn lại!

+0

Điều này thực sự không làm việc cho tôi cả (không xoay, không có đầu ra). Tôi tự hỏi nếu đó là thiết lập XML của tôi ..? –

1
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); 

Chúc may mắn!

2

Vì vậy, có câu trả lời ngắn và câu trả lời dài.

Câu trả lời ngắn gọn là việc xoay vòng bitmap và khung là một hàm phổ biến, thường được gọi là "xoay" và thường lấy điểm xoay vòng.

Câu trả lời dài hơn là tất cả đồ họa 2D và 3D đều biến thành một thủ thuật đại số ma trận. Đối với mỗi điểm: new_x = factor_1 * old_x + factor_2 * old_y + factor_3 ...

Những yếu tố này hoạt động rất tốt trong ma trận và lý do khiến ma trận trở nên phổ biến. Có một mẹo hay khi bạn kết hợp các phép biến đổi với nhau, vì vậy bạn có thể nêu ra các vấn đề của mình là "lấy canvas cũ, di chuyển nó sao cho điểm chạm là nguồn gốc, xoay nó, và di chuyển nó để nguồn gốc quay lại điểm xúc động. " Hoặc Matrix m = new Matrix() postTranslate (-touch_x, -touch_y) .postRotate (360/20) .postTranslate (touch_x, touch_y) để xoay nó bằng 1/20 vòng tròn mỗi lần. Sau đó, bạn chuyển ma trận cho bất kỳ hàm nào có ma trận "chuyển đổi".

Điều thú vị là bạn thực hiện tất cả các phép tính cho ma trận đó chỉ một lần, và sau đó sử dụng cùng 4 phép nhân trên mỗi điểm và một nhóm thêm. Trong thực tế, điều này là phổ biến đến nỗi các card video và bộ lệnh Intel đều thực hiện công cụ này trong phần cứng. Bạn cũng có thể chỉ nhân các hình ảnh kết quả một lần nữa bởi cùng một ma trận để có được một kế tiếp.

Bây giờ, nếu bạn thực sự yêu cầu hack đồ họa làm cách nào để làm điều này trong một số mã lắp ráp cực nhanh không có bộ nhớ, mẹo là chọn luân phiên và lỗi thành các chuỗi nhỏ nơi bạn không cần bộ đệm .Ví dụ, một vòng xoay 90 độ đơn giản đầu tiên sẽ hoán đổi bốn góc, sau đó nó hoán đổi (góc trên bên trái + 1 trái đi vào góc trên bên phải + 1 đi xuống phía dưới bên phải - 1 trái đi xuống dưới bên trái - 1 xuống, quay trở lại phía trên bên trái + 1). Những thủ thuật này thường chỉ quan trọng đối với các ràng buộc về bộ nhớ.

Cách quá nhiều thông tin. Hãy cho chúng tôi biết thêm về vấn đề của bạn.

0

tôi thấy this dụ và tôi thích làm việc nhiều hay ít như bạn cần, vui lòng xem ví dụ cho một sự hiểu biết tốt hơn về mã của tôi :)


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) { 
} 

} 

xml của chính

<?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> 
Các vấn đề liên quan