1. 程式人生 > >Android單點觸控技術 旋轉 平移 縮放等

Android單點觸控技術 旋轉 平移 縮放等

原文地址

相信大家使用多點對圖片進行縮放,平移的操作很熟悉了,大部分大圖的瀏覽都具有此功能,有些app還可以對圖片進行旋轉操作,QQ的大圖瀏覽就可以對圖片進行旋轉操作,大家都知道對圖片進行縮放,平移,旋轉等操作可以使用Matrix來實現,Matrix就是一個3X3的矩陣,對圖片的處理可分為四個基礎變換操作,Translate(平移變換)、Rotate(旋轉變換)、Scale (縮放變換)、Skew(錯切變換),如果大家對Matrix不太瞭解的話可以看看這篇文章(點選檢視),作者對每一種Matrix的變換寫的很清楚,但是如果使用一個手指對圖片進行縮放,平移,旋轉等操作大家是否瞭解呢,其實單手指操作跟多手指操作差不多,當然也是使用Matrix來實現的,無非是在縮放比例和旋轉角度的計算上面有些不一樣,也許你會有疑問,多點操作圖片縮放旋轉是兩個手指操作,平移的時候是一個手指操作,那麼你單手在圖片即平移,又縮放旋轉難道不會有衝突嗎?是的,這樣子肯定是不行的,我們必須將平移和縮放旋轉進行分開。如下圖


圖片外面的框是一個邊框,如果我們手指觸控的是上面的藍色小圖示我們就對其進行縮放旋轉操作,如果是觸控到其他的區域我們就對其進行平移操作,這樣就避免了上面所說的衝突問題,這裡對圖片的平移操作並沒有使用Matrix來實現,而是使用layout()方法來對其進行位置的變換。

計算縮放比例比較簡單,使用手指移動的點到圖片所在中心點的距離除以圖片對角線的一半就是縮放比例了,接下來就計算旋轉角度,如下圖


preMove是手指移動前一個點,curMove就是當前手指所在的點,還有一箇中心點center,知道三個點求旋轉的夾角是不是很簡單呢,就是線段a和線段c的一個夾角,假設夾角為o,  o的餘弦值 cos o = (

a * a + c * c - b * b) / (* a * c), 知道餘弦值夾角就出來了,但是這裡還有一個問題,我們在使用Matrix對圖片進行旋轉的時候需要區別順時針旋轉還是逆時針旋轉,順時針旋轉角度為正,所以上面我們只求出了旋轉的角度,並不知道是順時針還是逆時針。

具體怎麼求是順時針角度還是逆時針角度呢?有些同學可能會根據curMove和ProMove的x ,y 的大小來判斷,比如上面的圖中,如果curMove.x > proMove.x則為順時針,否則為逆時針,這當然是一種辦法,可是你想過這種方法只適合在第二象限,在第一,第三,第四象限這樣子判斷就不行了,當然你可以判斷當前的點在第幾象限,然後在不同的象限採用不同的判斷,這樣子判斷起來會很複雜。

有沒有更加簡單的方法來判斷呢?答案是肯定的,我們可以使用數學中的向量叉乘來判斷。假如向量A(x1, y1)和向量B(x2, y2),我們可以使用向量叉乘 |A X B| = x1*y2 - x2*y1 = |A|×|B|×sin(向量A到B的夾角), 所以這個值的正負也就是A到B旋轉角sin值的正負, 順時針旋轉角度0~180,sin>0, 順時針旋轉角度180~360或者說逆時針旋轉0~180,sin<0, 所以我們可以用個center到proMove的向量 叉乘 center到curMove的向量來判斷是順時針旋轉還是逆時針旋轉。

接下來我們就開始動手實現此功能,我們採用一個自定義的View來實現,這裡就叫SingleTouchView,直接繼承View, 從上面的圖中我們可以定義出一些自定義的屬性,比如用於縮放的圖片,控制縮放旋轉的小圖示,圖片邊框的顏色等,我定義瞭如下的屬性

  1. <declare-styleablename="SingleTouchView">
  2.     <attrname="src"format="reference"/><!-- 用於縮放旋轉的圖示 -->
  3.     <attrname="editable"format="boolean"/><!-- 是否處於可編輯狀態 -->
  4.     <attrname="frameColor"format="color"/><!-- 邊框顏色 -->
  5.     <attrname="frameWidth"format="dimension"/><!-- 邊框線寬度 -->
  6.     <attrname="framePadding"format="dimension"/><!-- 邊框與圖片的間距 -->
  7.     <attrname="degree"format="float"/><!-- 旋轉角度 -->
  8.     <attrname="scale"format="float"/><!-- 縮放比例 -->
  9.     <attrname="controlDrawable"format="reference"/><!-- 控制圖示 -->
  10.     <attrname="controlLocation"><!-- 控制圖示的位置 -->
  11.         <enumname="left_top"value="0"/>
  12.         <enumname="right_top"value="1"/>
  13.         <enumname="right_bottom"value="2"/>
  14.         <enumname="left_bottom"value="3"/>
  15.     </attr>
  16. </declare-styleable>

接下來就是自定義SingleTouchView的程式碼,程式碼有點長,註釋還是蠻詳細的

  1. package com.example.singletouchview;  
  2. import java.util.Arrays;  
  3. import java.util.Collections;  
  4. import java.util.List;  
  5. import android.content.Context;  
  6. import android.content.res.TypedArray;  
  7. import android.graphics.Bitmap;  
  8. import android.graphics.Bitmap.Config;  
  9. import android.graphics.Canvas;  
  10. import android.graphics.Color;  
  11. import android.graphics.Matrix;  
  12. import android.graphics.Paint;  
  13. import android.graphics.Paint.Style;  
  14. import android.graphics.Path;  
  15. import android.graphics.Point;  
  16. import android.graphics.PointF;  
  17. import android.graphics.drawable.BitmapDrawable;  
  18. import android.graphics.drawable.Drawable;  
  19. import android.util.AttributeSet;  
  20. import android.util.DisplayMetrics;  
  21. import android.util.FloatMath;  
  22. import android.util.TypedValue;  
  23. import android.view.MotionEvent;  
  24. import android.view.View;  
  25. import android.view.ViewGroup;  
  26. /** 
  27.  * 單手對圖片進行縮放,旋轉,平移操作,詳情請檢視 
  28.  *  
  29.  * @blog http://blog.csdn.net/xiaanming/article/details/42833893 
  30.  *  
  31.  * @author xiaanming 
  32.  * 
  33.  */
  34. publicclass SingleTouchView extends View {  
  35.     /** 
  36.      * 圖片的最大縮放比例 
  37.      */
  38.     publicstaticfinalfloat MAX_SCALE = 4.0f;  
  39.     /** 
  40.      * 圖片的最小縮放比例 
  41.      */
  42.     publicstaticfinalfloat MIN_SCALE = 0.3f;  
  43.     /** 
  44.      * 控制縮放,旋轉圖示所在四個點得位置 
  45.      */
  46.     publicstaticfinalint LEFT_TOP = 0;  
  47.     publicstaticfinalint RIGHT_TOP = 1;  
  48.     publicstaticfinalint RIGHT_BOTTOM = 2;  
  49.     publicstaticfinalint LEFT_BOTTOM = 3;  
  50.     /** 
  51.      * 一些預設的常量 
  52.      */
  53.     publicstatic

    相關推薦

    Android觸控技術 旋轉 平移

    原文地址 相信大家使用多點對圖片進行縮放,平移的操作很熟悉了,大部分大圖的瀏覽都具有此功能,有些app還可以對圖片進行旋轉操作,QQ的大圖瀏覽就可以對圖片進行旋轉操作,大家都知道對圖片進行縮放,平移,旋轉等操作可以使用Matrix來實現,Matrix就是一個

    Android觸控技術,對圖片進行平移旋轉操作

    相信大家使用多點對圖片進行縮放,平移的操作很熟悉了,大部分大圖的瀏覽都具有此功能,有些app還可以對圖片進行旋轉操作,QQ的大圖瀏覽就可以對圖片進行旋轉操作,大家都知道對圖片進行縮放,平移,旋轉等操作可以使用Matrix來實現,Matrix就是一個3X3的矩陣,對圖片的處理可

    Android觸控技術,實現對圖片的放大縮小平移,慣性滑動功能

    首先推薦一下鴻洋大大的打造個性的圖片預覽與多點觸控視訊教程,這套教程教我們一步一步實現了多點觸控實現對圖片的平移和縮放的功能,這篇文章我將在鴻洋大大的基礎之上做了一些擴充套件功能: 1.圖片的慣性滑動 2.圖片縮放小於正常比例時,鬆手會自動回彈成正常比例

    android 開源photoView的使用(/多觸控來進行圖片的智慧控制元件)

    簡介PhotoView 是一款擴充套件自Android ImageView,支援通過單點/多點觸控來進行圖片縮放的智慧控制元件。特性:支援單點/多點觸控,即時縮放圖片; 支援平滑滾動; 在滑動父控制元件下能夠執行良好;(例如:ViewPager) 當用戶的觸點改變是可以觸

    Android-觸控-多觸控

    <一>Android事件處理: 1、Android提供了兩種方式的事件處理: (1) 回撥事件處理:通過重寫元件特定的方法實現回撥事件處理,事件的發生者和事件的處理者是同 一個物件 監聽器的事件處理:通過編寫監聽類繫結元件實現監聽事件處理,事件的發生者和事件的處

    Android觸控與多觸控

    先測試單點觸控事件,它適用於所有android版本。我們在檢視中註冊一個OnTouchListener介面,並把觸控時間傳遞給這個介面實現。OnTouchListener介面只有一個方法:public abstract boolean onTouch(View  v,

    線性代數——矩陣解釋平移旋轉

    參考部落格: 線性代數:理解齊次座標 https://blog.csdn.net/yinhun2012/article/details/79566148 線性代數:矩陣變換圖形(二維平移縮放旋轉) https://blog.csdn.net/yinhun2012/article/de

    檢視的平移旋轉操作(transform)

    override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from

    canvas旋轉,平移,一二例

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style&g

    OpenGL 矩陣的旋轉-平移-

    1.  openGL的矩陣 openGL的矩陣是列優先排序的。就是說,矩陣的資料是存貯在一維陣列中,資料上傳到openGL處理的時候,會把一維資料的每一行當做列來處理。比如說,一個4*4的矩陣在陣列中的排列如下: matrix44 = { m0, m1,

    兩個手指多觸控 滑動 放大縮小

    using UnityEngine; using System.Collections; public class FingersTwo : MonoBehaviour {   public   GameObject  m1, m2;   int Z_Far = 0, Z_

    屬性動畫(旋轉,平移,,透明集合)

    MainActivity package com.example.animator; import android.animation.Animator; import android.animation.AnimatorListenerAdapter;

    OpenGL實現滑鼠繞任意軸旋轉/平移/

           剛剛學opengl的童鞋肯定有個苦惱的麻煩,只會繪製一個三角形,但是想像那些三維軟體那樣用滑鼠控制視角還是有點困難的,所以我就封裝了一個場景漫遊類:RoamingScenceManager,這個類使用非常方便,跟介面沒有半毛錢關係,可以在Qt,原生OpenGL

    Android觸控(放大、縮小、旋轉、位移)

    通過多點觸控實現圖片的放大、縮小、旋轉、位移效果。 private float oldX1 = 0; private float oldX2 = 0; private float oldY1 = 0; private float oldY2 =

    Android matrix偏移(平移),旋轉,傾斜的原理

    第一部分 Matrix的數學原理 在Android中,如果你用Matrix進行過影象處理,那麼一定知道Matrix這個類。Android中的Matrix是一個3 x 3的矩陣,其內容如下: Matrix的對影象的處理可分為四類基本變換: Translate   

    opencv 影象仿射變換 計算仿射變換後對應特徵的新座標 影象旋轉平移

    常常需要最影象進行仿射變換,仿射變換後,我們可能需要將原來影象中的特徵點座標進行重新計算,獲得原來影象中例如眼睛瞳孔座標的新的位置,用於在新得到影象中繼續利用瞳孔位置座標。 關於仿射變換的詳細介紹,請見上面連結的部落格。 我這裡主要介紹如何在已經知道原影象中若干特徵點的

    Android OpenGLES2.0(十)——OpenGL中的平移旋轉

    在前面的部落格中,所有的例子都是一個物件,類似繪製圓錐繪製圓柱,我們都是傳入一個引數,然後去控制那個圓面的位置,如果我們要繪製幾個個正方形,它的位置、大小、方向都是不相同的,按照那種方式該多麻煩啊。所以我們需要更好的辦法——矩陣變換。 什麼是矩陣 其實在

    canvas和白鷺引擎中平移旋轉

    都是 canvas 引擎 偏移 坐標 這一 text sla 偏移量 canvas中的 translate() 和白鷺引擎中的 .x 或者 .y 所導致的平移效果並不是移動 目標元素,而是移動目標元素父親所在的坐標系。 例如 bgg.translate(100,100)

    Matlab 圖像平移旋轉、鏡像

    more msh ret 結果 src end 初始 求解 http 今天學習了用Matlab實現對圖像的基本操作。在Matlab中,圖像是按照二維矩陣的形式表示的。所以對圖像的操作就是對矩陣的操作。 對圖像進行縮放、平移、旋轉,都可以轉化為矩陣的運算。 關於變換矩陣的構

    OpenGL實現平移旋轉

      #define GLEW_STATIC #include <GL\glew.h> #include <GLFW/glfw3.h> #include <iostream> #include "Shader.h" #define STB_IM