内容简介:© Young 2019-04-29 17:17Welcome to My给自己出了一道题如下:
© Young 2019-04-29 17:17
Welcome to My GitHub
给自己出了一道题如下:
题目
在某个大矩形中心有一个 黄色 的矩形,对该黄色矩形进行一系列 transform 变换得到灰色矩形;
以大矩形中心为 坐标原点 ,屏幕水平向左为 X 轴正方向 ,屏幕垂直向上为 Y 轴正方向 ,黄色矩形初始位置中心在坐标原点,根据其宽高可以得到其初始位置四个顶点的坐标 initPoints ;
那么求黄色矩形经过一系列变换后新的顶点坐标。
在线地址: https://newbieyoung.github.io/CSS_learn/transform3.html
解答
其实不管 CSS3 transform 属性 有多复杂,都是可以通过 getComputedStyle 直接获得最终变换矩阵的,具体方法实现如下:
//获得transform属性对应的矩阵形式
function getTransformMatrix(transform){
var $div = document.createElement('div');
$div.style.visibility = 'hidden';
$div.style.position = 'fixed';
//处理transform属性的兼容性
var transformProperty = 'transform';
if('transform' in $div.style){
transformProperty='transform'
} else if( 'WebkitTransform' in $div.style ){
transformProperty='webkitTransform'
} else if('MozTransform' in $div.style){
transformProperty='MozTransform'
} else if('OTransform' in $div.style){
transformProperty='OTransform'
}
$div.style[transformProperty] = transform;
document.body.appendChild($div);
var style = window.getComputedStyle($div);
var matrix = style[transformProperty];
document.body.removeChild($div);
return matrix;
}
通过 getTransformMatrix 函数可以获得以下形式的变换矩阵:
matrix(a, b, c, d, e, f); matrix(0.430963, 1.01542, -0.234879, 1.76697, 5, 40)
转换为三阶矩阵:
[a, c, e, b, d, f, 0, 0, 1];
不知道大家想过没有,明明是 2D 变换,转换为 三阶 矩阵干啥?
其实这里是引入了一个 齐次坐标 的概念,用 N+1 维的向量来表示 N 维向量;
比如在 2D 坐标系中某个点 (x, y) 可以在逻辑上表示为 (x*w, y*w, w) , w 即为新增的那个量。
引入齐次坐标的好处在于可以把 缩放 、 旋转 、 平移 等变换都统一转换成矩阵乘法的形式,这样不管进行多少次变换,都可以表示成矩阵连乘的形式了。
如果某个 2D 坐标系中点为 (x, y) ,转换为齐次坐标 (x, y, 1) ,那么经过上述变换后的新坐标为 (nx, ny, nz) :
nx = a * x + c * y + 1 * e; ny = b * x + d * y + 1 * f; nz = 0 + 0 + 1;
再把齐次坐标还原,最终坐标为 (nx, ny) 。
具体方法实现如下:
//计算矩阵变换后的坐标点
function getMatrixPoints(p,matrix){
var mat = matrixAnalyze(matrix);
// var mat3 = [mat[0],mat[2],mat[4],
// mat[1],mat[3],mat[5],
// 0,0,1];
// var mat3 = [a,c,e,
// b,d,f,
// 0,0,1];
// var newX = a * x + c * y + 1 * e;
// var newY = b * x + d * y + 1 * f;
// var newZ = 0 + 0 +1;
//计算变换后点坐标
var newX = mat[0] * p.x + mat[2] * p.y + 1 * mat[4];
var newY = mat[1] * p.x + mat[3] * p.y + 1 * mat[5];
var newZ = 0 + 0 +1;
return {x:newX/newZ,y:newY/newZ};
}
已知初始坐标 initPoints 和变换矩阵 matrix 相乘即可得到 matrixPoints ,到这里我以为这个题目已经解完了;
直到我尝试着在大矩形中用 红色 直线把计算得到的 matrixPoints 连起来才发现: 新坐标连接得到的图形和 CSS3 transform 变换得到灰色图形并不重合 ;
这也就意味着 上述计算过程有问题 !
在走了不少弯路之后我才意识到一个问题: CSS3 2D transform 坐标系和题目中设定的坐标系的 Y 轴正方向是相反的 ;
题目中设置的坐标系 Y 轴正方向是屏幕垂直向上而 CSS3 2D transform 坐标系的 Y 轴正方向是屏幕垂直向下。
因此在计算新坐标之前,需要对 getComputedStyle 得到的变换矩阵进行 镜像变换 ,从而转换为题目中设定坐标系的变换矩阵,也就是示例中 fixedMatrix ,最后计算的新坐标为 fixedPoints 。
用 蓝色 直线绘制出来就可以看到和灰色图形完全重合了。
总结
聊矩阵不聊坐标系都是耍流氓!
此外 张鑫旭 大神 2012 年的这篇文章 理解CSS3 transform中的Matrix(矩阵) 应该是有比较大问题的。
文中多次出现 方向不明、坐标轴错误 的坐标系,如果有看到建议改下。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Python基础教程
[挪] Magnus Lie Hetland / 袁国忠 / 人民邮电出版 / 2018-2-1 / CNY 99.00
本书包括Python程序设计的方方面面:首先从Python的安装开始,随后介绍了Python的基础知识和基本概念,包括列表、元组、字符串、字典以及各种语句;然后循序渐进地介绍了一些相对高级的主题,包括抽象、异常、魔法方法、属性、迭代器;此后探讨了如何将Python与数据库、网络、C语言等工具结合使用,从而发挥出Python的强大功能,同时介绍了Python程序测试、打包、发布等知识;最后,作者结合......一起来看看 《Python基础教程》 这本书的介绍吧!