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
分享到:
相关推荐
中国健康与养老追踪调查CHARLS是一项大型、跨学科的追踪调查项目,旨在收集中国老年人的健康、经济、社会和心理等多方面的信息。 一方面,随着医疗技术的进步和生活水平的提高,越来越多的老年人享受着健康长寿的生活;另一方面,慢性病、失能等健康问题仍然困扰着部分老年人,对他们的生活质量产生了严重影响。 数据年份:2020/2018/2015/2014/2013/2012/2011/2008 追访问卷、用户手册、原始数据等等 2008年两省试调查 2011年全国基线调查 2012年两省追踪调查 2013年全国追踪调查 2014年全国追踪调查(生命历程调查) 2015年全国追踪调查 2018年全国追踪调查 2020年全国追踪调查 Harmonized CHARLS
基于java的削面快餐店点餐服务系统的设计与实现.docx
项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
基于java的网上办公自动化系统设计与实现.docx
Chrome主题-开阔绿地草地主题
购物商城项目采用PHP+mysql有以及html+css jq以及layer.js datatables bootstorap等插件等开发,采用了MVC模式,建立一个完善的电商系统,通过不同用户的不同需求,进行相应的调配和处理,提高对购买用户进行配置….zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
小程序&预约报名&家政预约(源码+截图+源码导入教程和视频) 小程序&预约报名&家政预约(源码+截图+源码导入教程和视频) 小程序&预约报名&家政预约(源码+截图+源码导入教程和视频) 小程序&预约报名&家政预约(源码+截图+源码导入教程和视频) 小程序&预约报名&家政预约(源码+截图+源码导入教程和视频) 小程序&预约报名&家政预约(源码+截图+源码导入教程和视频) 小程序&预约报名&家政预约(源码+截图+源码导入教程和视频) 小程序&预约报名&家政预约(源码+截图+源码导入教程和视频) 小程序&预约报名&家政预约(源码+截图+源码导入教程和视频) 小程序&预约报名&家政预约(源码+截图+源码导入教程和视频) 小程序&预约报名&家政预约(源码+截图+源码导入教程和视频) 小程序&预约报名&家政预约(源码+截图+源码导入教程和视频) 小程序&预约报名&家政预约(源码+截图+源码导入教程和视频) 小程序&预约报名&家政预约(源码+截图+源码导入教程和视频) 小程序&预约报名&家政预约(源码+截图+源码导入教程和视频) 小程序&预约报名&家政预约(源码+截图+源码导入教程和视频) 小程序&
python贪吃蛇游戏
【作品名称】:基于java Swing+mysql实现简单的购物系统项目(说明文档+视频+源码) 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【项目介绍】:由Java swing实现的一款简单的购物程序,数据库采用的是mysql,该项目非常简单,实现了管理员对商品类型和商品的管理及用户注册登录后浏览商品、加入购物车、购买商品等功能,旨在学习Java 图形界面开发,所以非常适合Java初学者和学生用来学习参考,下面我们来看看如何配置运行; 将项目导入到eclipse(myeclipse也可以) 2.将项目导入后需要进行必要的配置才可以运行,接下来我演示如何配置。 3.接下来配置数据库连接信息,在dbutil里面配置数据库信息。 4.接下来我们来导入数据库文件,采用的是navicat数据库管理工具,如果你 【资源声明】:本资源作为“参考资料”而不是“定制需求”,代码只能作为参考,不能完全复制照搬。不一定能够满足所有人的需求,需要有一定的基础能够看懂代码,能够自行调试代码并解决报错,能够自行添加功能修改代码。
中低压蒸汽锅炉用户使用市政自来水+多效能BF防腐阻垢剂替代软化水或除盐水+阻垢+除氧+调PH值操作,不仅能大幅节省水资源、工业盐、电力、人力,消耗材料,实现节能减排,降本增效,防止地下水资源被污染,保护环境;还能有效解决有效防止锅炉水系统的腐蚀、结垢、失水量大、运行成本高等老大难问题。
数学基础:包括微积分、线性代数、概率论等对理解机器学习算法有帮助的基本数学。 Python:Python提供了非常丰富的工具包,非常适合学习者实现算法,也可以完成工业环境项目。作为主流的深度学习框架,例如当前最流行的两个AI框架TensorFlow、PyTorch都以Python作为语言首选。另外,主流的在线课程(比如Andrew Ng在Coursera的深度学习系列课程)用Python作为练习项目的语言。在这部分,我将包括Python语言基础和机器学习常用的几个库,包括Numpy、Pandas、matplotlib、Scikit-Learn等。 机器学习:介绍主流的机器学习算法,比如线性回归、逻辑回归、神经网络、SVM、PCA、加权算法等等。 深度学习:介绍原理和常见的模型(如CNN、RNN、LSTM、GAN等)和深度学习的框架(TensorFlow、Keras、PyTorch)。 强化学习:介绍强化学习的简单原理和实例。 实践项目:这里将结合几个实际项目的演示比较完整的讲解。另外结合Kaggle、阿里云天池演示演示。 阅读论文:如果你追求更高、更深入的研究时,看深度学习各细分领域的
c 在C++中,有许多经典程序示例,可以用于学习和实践。下面是一个简单的示例,演示了如何使用C++标准库中的输入输出流(iostream)进行基本的输入输出操作。 示例:Hello, World! 程序 #include <iostream> // 引入输入输出流库 int main() { std::cout << "Hello, World!" << std::endl; // 输出 "Hello, World!" 到控制台 return 0; // 程序执行成功 } ### 示例:加法计算器 #include <iostream> int main() { int num1, num2, sum; // 提示用户输入两个整数 std::cout << "Enter two integers to add: "; std::cin >> num1 >> num2; // 从标准输入读取两个整数 // 计算和 sum = num1 + num2; // 输出结果 std::cout << "Th
管理员登录,通过填写用户名、密码、权限等信息,输入完成后选择登录即可进入校园快领服务系统 管理员登录进入校园快领服务系统可以查看首页、个人中心、快递员管理、学生管理、快递信息管理、取货信息管理、订单信息管理、接单信息管理、服务评价管理、订单投诉管理、留言板管理、论坛管理、系统管理等内容 项目关键技术 开发工具:IDEA 、Eclipse 编程语言: Java 数据库: MySQL5.7+ 后端技术:ssm 前端技术:Vue 关键技术:springboot、SSM、vue、MYSQL、MAVEN 数据库工具:Navicat、SQLyog
项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用
HFSS-MATLAB-API工具库及使用实例——矩形微带贴片模型
基于java的的个人博客网站的设计与实现设计与实现.docx
均包含代码,文章,部分项目包含ppt
预约住院系统,用户就可以在网上预约医院的专家、专科号。它能更好的改善就医环境,简化就医环节,节约就医时间,真正体现了以病人为中心,切从方便患者出发,符合当今医院人性化温馨服务的理念。本医院住院管理系统采用的数据库是Mysql,使用SSM框架开发。 医院住院管理系统,在医院住院管理系统首页可以查看首页、医护人员、药品信息、健康讲坛、个人中心、后台管理、医疗交流等内容 项目关键技术 开发工具:IDEA 、Eclipse 编程语言: Java 数据库: MySQL5.7+ 后端技术:ssm 前端技术:Vue 关键技术:springboot、SSM、vue、MYSQL、MAVEN 数据库工具:Navicat、SQLyog
项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用
基于java的民宿住宿管理系统设计与实现.docx