在上一篇文章中,我們講到,在Android中,scale(縮放),rotation(旋轉)和 translation(平移)都是以矩陣(Matrix)的形式定義的,實際上在圖形學中,這些平面圖形的變換都是以矩陣的形式存在的。先來回顧一下,下面,左中右分別scale(縮放),rotation(旋轉)和 translation(平移)在Android中的矩陣表示:
如果只是單純的應用某一個變換,我們都知道直接用矩陣去乘上對應的點就可以了。但是對於縮放和旋轉來說,它們的軸點是基於原點(0,0)的,如,我們將它縮小1倍,代碼如下:<喎?http://www.bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+PHByZSBjbGFzcz0="brush:java;">public void onDraw(Canvas canvas){canvas.drawBitmap(bitmap, 0, 0, null);matrix.reset();matrix.postScale(0.5f, 0.5f);canvas.drawBitmap(bitmap, matrix, null);}
則其效果如右圖所示:
那麼我們如果想讓它基於圖片中心縮放,應該該怎麼辦?我們上一篇文章也說過了,要用到組合變換,
1)先將圖片由中心平移到原點,這是應用變換 T
2)對圖應用縮放變換 S
3)再將圖片平移回到中心,應用變換 -T
下面給出它們的組合變換的公式:
在Android中的代碼如下:
public void onDraw(Canvas canvas){canvas.drawBitmap(bitmap, 0, 0, null);matrix.reset();matrix.postScale(0.5f, 0.5f);matrix.preTranslate(-pivotX, -pivotY);matrix.postTranslate(pivotX, pivotY);canvas.drawBitmap(bitmap, matrix, null);}我們看一下加上平移之後的(其中pivotX 和 pivotY 是圖片的中心):
我們看到代碼中,我們在進行了scale之後呢,還給圖片設定了下面兩個平移的變換:
matrix.preTranslate(-pivotX, -pivotY);matrix.postTranslate(pivotX, pivotY);
什麼是PreTranlsate呢,什麼又是postTranslate呢?我們先來看一下Android中的定義吧。
preTranslate:
/** * Preconcats the matrix with the specified translation. * M' = M * T(dx, dy) */ public boolean preTranslate(float dx, float dy) { return native_preTranslate(native_instance, dx, dy); }
postTranslate:
/** * Postconcats the matrix with the specified translation. * M' = T(dx, dy) * M */ public boolean postTranslate(float dx, float dy) { return native_postTranslate(native_instance, dx, dy); }
我們可以看到,pre是拿當前的矩陣乘以T,而post是拿T來乘以當前的矩陣,(矩陣的乘法是不滿足交換率的,所以這兩種乘法的結果是不一樣的)
在圖形學中,矩陣M右乘A,表示的是 A * M,而矩陣 M 左乘 A,則表示的是 M * A,可以形象地理解為右乘就是從右邊乘進來,左乘就是從左邊乘進來。
一比較,我們可以看出,pre其實執行的就是右乘的操作,而post執行的就是左乘的操作。
這是因為,在影像處理中,越靠近右邊的矩陣越先執行,所以pre(也就是先的意思)所設定的矩陣T(Scale,Rotation也是一樣的)就會先於其一開始設定的Scale執行,而post(後的意思)的因為是左乘,所以它會放在最左邊,那麼就會最後執行。
所以,上面三步的意思其實就是:
1)在當前的矩陣左邊加一個Scale的操作,因為之前沒有其的操作(reset了),那麼當前的矩陣其實就只是 S 了。
2)在當前的矩陣(S)執行前,先執行一個平移到原點的操作(preTranslate),其實也就是進行右乘(S * T)。
3)在當前的矩陣(S * T)執行後,再執行一個從原點平移到中心點的操作(postTranslate),也就是進行一個左乘(-T * S * T)。
這就是Android中矩陣(Matrix)前乘和後乘所對應的圖形學中矩陣中右乘和左乘的操作了。
不知道理解有沒有錯誤,如有錯誤 ,希望有朋友能夠指正,謝謝大家,另祝大家新年快樂!
下面是上一篇文章,關於圖形學中矩陣和圖形變換的關係,有興趣的朋友也可以讀一下:
2D平面中關於矩陣(Matrix)跟圖形變換的講解