`

2011.10.12(3)——— android Matrix学习02

阅读更多
2011.10.12(3)——— android Matrix学习02

参考:http://www.iteye.com/topic/713869
http://www.moandroid.com/?p=1771

首先声明一下 上一节是有错误的


这张图是错误的







这两张图才是正确的

解释一下 假设矩阵为[a1,a2,a3][b1,b2,b3][c1,c2,c3]

如图所示 那么
平移为a3 b3
缩放为a1 b2
旋转为a1 a2 b1 b2

这是我大概的理解



下面 针对不同的变化 做一下分析

首先 声明一下 matrix最开始的矩阵是[1,0,0][0,1,0][0,0,1]
 
下面的都是针对单一变化的分析
1、平移

现设点P0(x0, y0)进行平移后,移到P(x,y),
其中x方向的平移量为△x,y方向的平移量为△y(相当于_matrix.postTranslate(△x, △y);)
那么,点P(x,y)的坐标为:
x = x0  + △x
y = y0  + △y
采用矩阵表达上述如下:
[1,0,△x][0,1,△y][0,0,1] * [x0][y0][1] = [x0+△x][y0+△y][1]

2、缩放
现设点p0(x0 ,y0)进行缩放,其中x放大a倍,y放大b倍,假设p0缩放后的坐标p(x,y)
那么,点P(x,y)的坐标为:
x = x0 * a
y = y0 * b
采用矩阵表达上述如下:
[a,0,0][0,b,0][0,0,1] * [x0][y0][1] = [x0 * a][y0 * b][1]


3、旋转

现设点P0(x0, y0)旋转θ角后的对有点为P(x, y)。通过使用向量,我们得到如下:
x0 = r  cosα
y0 = r  sinα
x = r cos(α-θ) = x0 cosθ+ y0 sinθ
y = r sia(α-θ) = -x0 sinθ+y0 cosθ
采用矩阵表达上述如下:
[cosX,-sinX,0][sinX,cosX,0][0,0,1] * [x0][y0][1] = x0 cosθ+ y0 sinθ][-x0 sinθ+y0 cosθ][1]


我的测试代码 如下:
package com.lp.matrix;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.util.Log;
import android.view.View;

/**
 * 一个简单的Matrix例子
 * 
 * @author lp
 * lipeng88213@126.com
 * http://lipeng88213.iteye.com/
 * 2011-10-12
 * 上午11:29:19
 */
public class MatrixView extends View {

	private final static String TAG = "lp";
	private Context _context;
	private Bitmap _bitmap;
	private Matrix _matrix = new Matrix();
	
	public MatrixView(Context context) {
		super(context);
		this._context = context;
		//init();
//		init2();
		init3();
	}

	//例子01
	private void init(){
		//得到图片
		_bitmap = ((BitmapDrawable)getResources().getDrawable(R.drawable.a)).getBitmap();
		//得到30°的sin和cos值
		//顺时针是正数,我们这个是逆时针转动30°
		float sinValue = (float)Math.sin(-Math.PI/6);
		float cosValue = (float)Math.cos(-Math.PI/6);
		
		//给Matrix赋值 按照固定的顺序
		//
		//cosX	-sinX	translateX
		//sinX	cosX	translateY
		//0		0		scale
		//
		//解释
		//上面的 sinX 和 cosX ,表示旋转角度的 cos 值和 sin 值,注意,旋转角度是按顺时针方向计算的。 
		//translateX 和 translateY 表示 x 和 y 的平移量。 
		//scale 是缩放的比例, 1 是不变, 2 是表示缩放 1/2  后来才知道 这个并不是缩放的 而是控制等比变换的
		_matrix.setValues(new float[]{
				cosValue,-sinValue,100,
				sinValue,cosValue,100,
				0,0,2
		});
	}
	//例子02
	private void init2() {
		_bitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.a)).getBitmap();

		/*
		 * 首先,将缩放为100*100。这里scale的参数是比例。有一点要注意,如果直接用100/ bmp.getWidth()的话,会得到0,
		 * 因为是整型相除,所以必须其中有一个是float型的,直接用100f就好。
		 */
		_matrix.setScale(100f / _bitmap.getWidth(), 50f / _bitmap.getHeight());
		// 平移到(100,100)处
		_matrix.postTranslate(100, 100);
		// 倾斜x和y轴,以(100,100)为中心。
		_matrix.postSkew(-0.2f, 0.5f, 100, 100);
		
	}
	
	//例子03
	private void init3() {
		_bitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.a)).getBitmap();

		
		//
		//cosX	-sinX	translateX
		//sinX	cosX	translateY
		//0		0		scale
		//
		
		//执行_matrix.postTranslate(250, 250);后的矩阵为
		//Matrix{[1.0, 0.0, 100.0][0.0, 1.0, 250.0][0.0, 0.0, 1.0]}
		//紧接着_matrix.postRotate(30);得到的矩阵
		//Matrix{[0.8660254, -0.5, -38.39746][0.5, 0.8660254, 266.50635][0.0, 0.0, 1.0]}

		//很明显  平移距离x y都变化了
//		_matrix.postTranslate(100, 250);
//		_matrix.postRotate(30);
		
		
		//执行_matrix.postRotate(30);后的矩阵为
		//Matrix{[0.8660254, -0.5, 0.0][0.5, 0.8660254, 0.0][0.0, 0.0, 1.0]}
		//紧接着_matrix.postTranslate(250, 250);得到的矩阵
		//Matrix{[0.8660254, -0.5, 250.0][0.5, 0.8660254, 250.0][0.0, 0.0, 1.0]}
		//这个平移的距离没有变化
//		_matrix.postRotate(30);
//		_matrix.postScale(100f/_bitmap.getWidth(), 100f/_bitmap.getHeight());
//		_matrix.postTranslate(250, 250);
		
		//这个全部执行完后的矩阵为:
		//Matrix{[0.5235602, 0.0, 52.35602][0.0, 2.2727273, 227.27272][0.0, 0.0, 1.0]}
		//可以看出来 原本为cosX的两个位置发生了变化 但是 按照我们的理解 缩放应该改变的为scale位置的数才对啊?
		//所以 可以证明 我们上面的
		//cosX	-sinX	translateX
		//sinX	cosX	translateY
		//0		0		scale
		//并不是完全正确的
		//
//		_matrix.postTranslate(100, 100);
//		_matrix.postScale(100f/_bitmap.getWidth(), 100f/_bitmap.getHeight());
		
		
		//执行_matrix.postRotate(30);后的矩阵为
		//Matrix{[0.8660254, -0.5, 0.0][0.5, 0.8660254, 0.0][0.0, 0.0, 1.0]}
		//
		//紧接着_matrix.postScale(2, 3);得到的矩阵
		//Matrix{[1.7320508, -1.0, 0.0][1.5, 2.598076, 0.0][0.0, 0.0, 1.0]}

//		_matrix.postRotate(30);
//		_matrix.postScale(2, 3);
		
		//总结 
		//1、
		//通过上面的 我们可以看出来 我们涉及到平移操作的复合变化时,平移最好放到最后来执行
		//否则 就会造成上面的问题
		//
		//前提:
		//假如 矩阵为[a1,a2,a3][b1,b2,b3][c1,c2,c3]
		//
		//2、
		//当我们执行平移操作matrix.postTranslate(dx, dy);后
		//又执行了旋转、缩放等其他操作的时候 a3和b3就会发生变化  它的运算规则是在这样的 (此矩阵为执行其他操作后的矩阵,以其他值来算a3 b3)
		//a3 = a1*dx + a2*dy
		//b3 = b1*dx + b2*dy
		//
		//3、
		//执行_matrix.postScale(sx,sy)的时候 会改变a1、a2和b1、b2的值
		//a1 = a1*sx  a2 = a2*sx
		//b1 = b1*sy  b2 = b2*sy
		
	}
	//例子04 垂直镜像
	private void init4() {
		_bitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.a)).getBitmap();
		
		//按说 翻转180° 应该就可以翻转过来 
		//但是 如果不加postTranslate 是不会显示出来的
		//因为 垂直翻转 按理说 应该是x = x0 y = -y0  矩阵应该为
		//1	0	0
		//0	-1	0
		//0	0	1
		//这样才能保证  这个矩阵 乘以矩阵
		//x0
		//y0
		//1
		//的时候 得到的矩阵为
		//x0
		//-y0
		//1
		//也就是
		//x
		//y
		//1
		//正好得到   这个矩阵式竖着的
		//如果 _matrix.postRotate(180); 则推到出来的矩阵为
		//-1	0	0
		//0	-1	0
		//0	0	1
		//而这矩阵 乘以矩阵
		//-x0
		//y0
		//1
		//的时候 得到的矩阵为
		//-x0
		//-y0
		//1
		//这样 就跑道屏幕的对角线那个象限了 看不到了
		//所以 加上_matrix.postTranslate(_bitmap.getWidth(), _bitmap.getHeight()); 让她再平移过来
//		_matrix.postRotate(180);
//		_matrix.postTranslate(_bitmap.getWidth(), _bitmap.getHeight());
		
		//Matrix{[1.0, 0.0, 0.0][0.0, -1.0, 0.0][0.0, 0.0, 1.0]}
		//这个应该可以理解为 先旋转了180° 然后y轴缩放了-1 也就是 变到第二象限了
		_matrix.setScale(1.0f, -1.0f);
		//上面的执行完毕后 和矩阵[x0][y0][1] 相乘后 得到[x0][-y0][1]
		//映射到屏幕的上方了 也就是x轴的上方了 还是看不到 所以 要给y轴加上图片的高度 让其出现在屏幕里 
		//这个效果 和上面的一样 
		//Matrix{[1.0, 0.0, 0.0][0.0, -1.0, 44.0][0.0, 0.0, 1.0]}
		_matrix.postTranslate(0, _bitmap.getHeight());
	}


	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		
		canvas.drawBitmap(_bitmap, _matrix, null);
//		canvas.drawBitmap(_bitmap, 0, 0, null);
		Log.i(TAG, _matrix.toString());
	}
	
	
	
}



结论:

例子01:

我们可以通过_matrix.setValues来直接设置矩阵

例子02:



例子03:

1、通过上面的 我们可以看出来 我们涉及到平移操作的复合变化时,平移最好放到最后来执行
否则 就会造成上面的问题
前提:
假如 矩阵为[a1,a2,a3][b1,b2,b3][c1,c2,c3]

2、
当我们执行平移操作matrix.postTranslate(dx, dy);后
又执行了旋转、缩放等其他操作的时候 a3和b3就会发生变化  它的运算规则是在这样的 (此矩阵为执行其他操作后的矩阵,以其他值来算a3 b3)
a3 = a1*dx + a2*dy
b3 = b1*dx + b2*dy

3、
执行_matrix.postScale(sx,sy)的时候 会改变a1、a2、a3和b1、b2、b3的值
a1 = a1*sx  a2 = a2*sx a3 = a3*sx
b1 = b1*sy  b2 = b2*sy b3 = b3*sy

例子04:

设置垂直镜像
_matrix.setScale(1.0f, -1.0f);
_matrix.postTranslate(0, _bitmap.getHeight());
或者
_matrix.postRotate(180);
_matrix.postTranslate(_bitmap.getWidth(), _bitmap.getHeight());



  • 大小: 17.1 KB
  • 大小: 27.4 KB
  • 大小: 31 KB
  • 大小: 7.1 KB
分享到:
评论

相关推荐

    2011.10.13(2)——— android Matrix学习03

    这篇博客“2011.10.13(2)——— android Matrix学习03”可能深入探讨了Matrix类的一些高级用法和实践技巧。虽然描述中没有提供具体信息,但从标题可以推断,这可能是系列教程的第三部分,继续深化对Matrix的理解。...

    从一条电线到建立一个网络视频.zip

    02 D02 网络基础——光纤和射频编码.mp4 03 D03 网络基础——时钟同步与曼彻斯特编码.mp4 04 D04 网络基础——实际网络中0和1是如何传输的.mp4 05 D05 网络基础——0和1如何变成网络中的帧.mp4 06 D06 网路基础——...

    基于因子分析的我国A股上市...争力评价——以医药企业为例_张澳.caj

    基于因子分析的我国A股上市...争力评价——以医药企业为例_张澳.caj

    Android经典项目——AndroidStudio版本.zip

    Android经典项目——AndroidStudio版本.zip。 经典项目——AndroidStudio版本.zip经典项目——AndroidStudio版本.zip Android 经典项目 源码

    城市规划毕业设计——国际酒店景观设计(毕业论文+答辩PPT).zip

    城市规划毕业设计——国际酒店景观设计(毕业论文+答辩PPT).zip 城市规划毕业设计——国际酒店景观设计(毕业论文+答辩PPT).zip 城市规划毕业设计——国际酒店景观设计(毕业论文+答辩PPT).zip 城市规划毕业设计...

    JDK_1.7,amd64_ubuntu,安装包,直接下载安装即可完成1.7版本的SDK包。原生安装,不用配置环境变量,

    1,安装说明.txt ——————————安装手册 2,jdk-170.tar.gz ——————————JDK1.7deb包 3,switch_java.sh -------------------------java其它版本切换 4,check_java.sh———————————版本...

    嵌入式成品项目-无线接收时钟.zip

    嵌入式成品项目——无线接收时钟.zip嵌入式成品项目——无线接收时钟.zip嵌入式成品项目——无线接收时钟.zip嵌入式成品项目——无线接收时钟.zip嵌入式成品项目——无线接收时钟.zip嵌入式成品项目——无线接收时钟...

    python项目——Word助手.zip

    python项目——Word助手.zip python项目——Word助手.zip python项目——Word助手.zip python项目——Word助手.zip python项目——Word助手.zip python项目——Word助手.zip python项目——Word助手.zip python项目...

    微信小程序——人脸检测(截图+源码).zip

    微信小程序——人脸检测(截图+源码).zip 微信小程序——人脸检测(截图+源码).zip 微信小程序——人脸检测(截图+源码).zip 微信小程序——人脸检测(截图+源码).zip 微信小程序——人脸检测(截图+源码).zip ...

    wavecom 模块常用AT指令手册.pdf

    **3. AT+CGMR** —— 查询模块的软件版本。这对于确定模块功能和兼容性至关重要,确保其与开发或使用的软件相匹配。 **4. AT+CGSN** —— 获取GSM模块的IMEI(国际移动设备标识)序列号。IMEI是设备唯一身份证明,...

    C语言项目——MP3音乐播放器.zip

    C语言项目——MP3音乐播放器.zip C语言项目——MP3音乐播放器.zip C语言项目——MP3音乐播放器.zip C语言项目——MP3音乐播放器.zip C语言项目——MP3音乐播放器.zip C语言项目——MP3音乐播放器.zip C语言项目——...

    python项目——DIY字符画.zip

    python项目——DIY字符画.zip python项目——DIY字符画.zip python项目——DIY字符画.zip python项目——DIY字符画.zip python项目——DIY字符画.zip python项目——DIY字符画.zip python项目——DIY字符画.zip ...

    microsoftrootcertificateauthority2011.cer

    microsoftrootcertificateauthority2011.cer - 教程详情https://blog.csdn.net/Dream_Weave/article/details/125408661

    C语言项目——企业员工管理系统.zip

    C语言项目——企业员工管理系统.zip C语言项目——企业员工管理系统.zip C语言项目——企业员工管理系统.zip C语言项目——企业员工管理系统.zip C语言项目——企业员工管理系统.zip C语言项目——企业员工管理系统....

    城市规划毕业设计——尚上人家景观设计(毕业论文+答辩PPT+CAD图+设计图+效果图).zip

    城市规划毕业设计——尚上人家景观设计(毕业论文+答辩PPT+CAD图+设计图+效果图).zip 城市规划毕业设计——尚上人家景观设计(毕业论文+答辩PPT+CAD图+设计图+效果图).zip 城市规划毕业设计——尚上人家景观设计...

    微信小程序——移动端商城(截图+源码).zip

    微信小程序——移动端商城(截图+源码).zip 微信小程序——移动端商城(截图+源码).zip 微信小程序——移动端商城(截图+源码).zip 微信小程序——移动端商城(截图+源码).zip 微信小程序——移动端商城(截图+...

    微信小程序——图书管理系统(截图+源码).zip

    微信小程序——图书管理系统(截图+源码).zip 微信小程序——图书管理系统(截图+源码).zip 微信小程序——图书管理系统(截图+源码).zip 微信小程序——图书管理系统(截图+源码).zip 微信小程序——图书管理...

    微信小程序——手势解锁(截图+源码).zip

    微信小程序——手势解锁(截图+源码).zip 微信小程序——手势解锁(截图+源码).zip 微信小程序——手势解锁(截图+源码).zip 微信小程序——手势解锁(截图+源码).zip 微信小程序——手势解锁(截图+源码).zip ...

    小学语文一年级下册反义及量词练习大全.pdf

    这篇小学语文一年级下册的反义词及量词练习主要涵盖了语言学习的基础概念,旨在帮助学生掌握汉语中的基本词汇关系和量词的正确使用。 反义词是汉语词汇中非常重要的一部分,它指的是意思相反或相对的词语。在给出的...

    微信小程序——全屏动画滚动(截图+源码).zip

    微信小程序——全屏动画滚动(截图+源码).zip 微信小程序——全屏动画滚动(截图+源码).zip 微信小程序——全屏动画滚动(截图+源码).zip 微信小程序——全屏动画滚动(截图+源码).zip 微信小程序——全屏动画...

Global site tag (gtag.js) - Google Analytics