2011-09-14 141 views
8

我有一個箭頭圖像,我想從0旋轉到180度(如米針)。箭頭的一個點固定在屏幕的中間和底部,箭頭應移動。箭頭的長度是固定的(這是圖像)。此外,我有兩個按鈕,我需要箭頭在左側按鈕被觸摸時向左轉,而在右側按鈕被觸摸時向右轉。Android,我如何在固定點周圍旋轉箭頭(圖像)?

這個過程的邏輯是什麼?

enter image description here

+0

使用矩陣來應用旋轉。 –

+1

確切的重複http://stackoverflow.com/questions/4166917/android-how-to-rotate-a-bitmap-on-a-center-point – Ronnie

+0

我建議你到用戶@Emiam答案,這將不會使用CPU就像Matrix一樣。 –

回答

2

你有可能動畫的Android使用3D旋轉工作,並嘗試也usong矩陣旋轉......我對這個位圖碼.........

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 

還要檢查這個

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

+0

這不是一個好的策略,因爲Bitmap.createBitmap方法非常慢,並且每幀這樣做會殺死FPS速率。 – Emiam

5

這其實是很簡單,如果你使用的是帆布做繪圖(就像你在案例中那樣)。當用戶點擊

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

度將是您增加/減少一個整數值:

既然你知道該點周圍的圖像應該旋轉座標,你可以像下面這樣做L或R按鈕。 canvas.rotate照顧其餘的!

+0

這實際上根本不適用於我(不旋轉,不輸出)。我想知道如果這是我的XML設置..? –

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

祝你好運!

2

所以有簡答題和長答案。

簡短的回答是,位圖和畫布的旋轉是一個常見的功能,通常稱爲「旋轉」,並通常採取圍繞其旋轉的點。

較長的答案是,所有的二維和三維圖形都轉化爲矩陣代數的訣竅。對於每一個點: 的new_x = factor_1 * old_x + factor_2 * old_y + factor_3 ...

這些因素的工作真的很好的矩陣,也就是爲什麼矩陣事情變得如此受歡迎。將變換鏈接在一起有一個很酷的竅門,所以你可能會將問題說成「拿起舊的畫布,移動它,以便觸摸的點是原點,旋轉它,然後移動它,以便原點返回觸摸點「。或矩陣m =新的矩陣()。postTranslate(-touch_x,-touch_y).postRotate(360/20).postTranslate(touch_x,touch_y)每次旋轉1/20的圓。然後將矩陣傳遞給任何採用「變換」矩陣的函數。

很酷的事情是,你只需對該矩陣進行一次所有計算,然後對每個點和一堆加法使用相同的4次乘法。事實上,這是很常見的,視頻卡和英特爾指令集都在硬件中完成這些工作。你也可以用相同的矩陣重新生成結果圖像,以獲得下一個。

現在,如果你確實需要圖形破解,我該如何在沒有內存的快速彙編代碼中執行此操作,訣竅是將旋轉和錯誤選擇到不需要緩衝區的小鏈中。例如,一個簡單的90度旋轉將首先交換四個角,然後交換(左上角+1左上角進入右上角+1下角,右下角 - 左下角 - 左下角--1下角,回到左上角+ 1)。這些技巧通常只對內存限制很重要。

方式太多的信息。告訴我們更多關於你的問題。

0

我看到this例子,我適應工作或多或少像你需要,請參閱更好地理解我的代碼:)


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中的示例
<?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>