- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
theme: qklhk-chocolate
- 引言:你有没好奇过,在一个使用了transform变换的元素上使用window.getComputedStyle(htmlElement)['transform'] 查询出来的值代表什么?
以两个二阶齐次矩阵相乘为例
[ [ [
a11,a12, * b11,b12, = a11*b11 + a12* b21 , a11*b12 + a12*b22,
a21,a22 b21,b22 a21*b11 + a22* b21 , a21*b12 + a22*b22
] ] ]
由此,可以看到两个矩阵相乘就是拿第一个的每一行,乘以第二个的每一列,因此两个矩阵相乘也有个规定就是第一个矩阵的列数(每一行元素的个数),要与第二个矩阵的行数(每一列元素的个数)相等才可以发生乘法运算.
首先回答第一个问题: 由window.getComputedStyle(htmlElement)['transform']查询出来的值代表一个matrix3d函数的参数,形如 matrix3d(a1, b1, c1, d1, a2, b2, c2, d2, a3, b3, c3, d3, a4, b4, c4, d4) 。
其中a1 b1 c1 d1 a2 b2 c2 d2 a3 b3 c3 d3,代表了线性变换,a4 b4 c4 d4代表的是位移变换。若空间中点的表示是一个列向量表示,那么,他的矩阵形式应该是这样的
a1 a2 a3 a4
b1 b2 b3 b4
c1 c2 c3 c4
d1 d2 d3 d4
在下边的例子中我们都假定空间中的点是以列向量形式表示的。使用右手坐标系.
3d变换的初始矩阵如下
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
这是一个单位矩阵,这样的矩阵满足矩阵乘法运算的交换律,且和整数中1的作用一样,乘以任何数还是任何数,因此单位矩阵与其他矩阵的乘法运算不产生任何效果.
translate代表一个位移变换,3d的translate变换矩阵对应的是一个如下的4阶齐次矩阵 T
1 0 0 dx
0 1 0 dy
0 0 1 dz
0 0 0 1
假设空间内某个点D的坐标形如
x
y
z
1
给他施加一个translate矩阵之后就可以得到的结果为 T*D
1*x + 0*y + 0 * z + dx, x + dx
0*x + 1*y + 0 * z + dy, = y + dy
0*x + 0*y + 1 * z + dz, z + dz
0 + 0 + 0 + 1, 1
以上的变换写成matrix3d函数的形式就是: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, dx, dy, dz, 1) 等价于: translate3d(x,y,z) .
变换矩阵的前三行可以分别看做一个空间坐标系上对某个点要施以某种变换的x,y,z轴上的表示,每一行的前三列代表x,y,z轴上具体要有的变换,比如在位移变换矩阵中第一行代表x轴上该点要做的变换,那么对应的y,z的值为0。(这是我个人的一点思考。可跳过。。。) 。
scale表示的是一个缩放变换,缩放的具体数值体现在主对角线上,比如一个1.5倍的缩放矩阵S
1.5 0 0 0
0 1.5 0 0
0 0 1.5 0
0 0 0 1
给上边的点D施加一个缩放矩阵得到的结果是 S*D
1.5*x + 0*y + 0*z + 0 * 1 1.5x
0*x + 1.5*y + 0*z + 0 * 1 = 1.5y
0*x + 0*y + 1.5*z + 0 * 1 1.5z
0*x + 0*y + 0*z + 1 * 1 1
等价于: matrix3d(1.5, 0, 0, 0, 0, 1.5, 0, 0, 0, 0, 1.5, 0, 0, 0, 0, 1) 可简写为: scale3d(1.5, 1.5, 1.5) 。
rotate 代表旋转 。
二维平面的rotate代表某个点绕着某个点旋转,一个二维变换可以使用一个三阶齐次矩阵表示,其矩阵的推导可以这么推导
1 0 0
0 1 0
0 0 1
将两个单位向量分别在x y轴上旋转θ角度,得到的A'便是x轴上旋转矩阵的值,得到的B' 便是y轴上旋转矩阵的值,因此2d的旋转矩阵是这样的(图片上的坐标系是以行向量表示的,为了统一 我们进行一次转置)
cos0 -sin0
sin0 cos0
在一个3d空间中,旋转不再是绕某个点的旋转,而是绕某个轴的旋转(x,y,z轴),以绕x轴的旋转举例(这个图有点出入,实际BB'应该与y轴是平行的,AA'与Z轴平行,理解就好,没办法绘画功底实在太差 - -,绕某个轴旋转就是想象该条轴不动然后另一条与他垂直的轴绕着其旋转):
因此绕x轴的旋转矩阵可以写成这样:
1 0 0 0
0 cos0 -sin0 0
0 sin0 cos0 0
0 0 0 1
我们可以写一个 rotateX(60deg) ,那么对应的matrix3d的参数就是: matrix3d(1, 0, 0, 0, 0, 0.5, 0.866025, 0, 0, -0.866025, 0.5, 0, 0, 0, 0, 1) 同理可得出绕z轴和y轴的旋转矩阵
Z:
cos0 -sin0 0 0
sin0 cos0 0 0
0 0 1 0
0 0 0 1
Y:
cos0 0 sin0 0
0 1 0 0
-sin0 0 cos0 0
0 0 0 1
至此,css中的3d变换大体上讲完了,然后将以上几种矩阵经过不同组合相乘就能得到复合变换,值得注意的是 矩阵乘法一般不满足交换律,所以运算顺序还是比较重要的.
那为什么图形变换在计算机中一般使用矩阵表示呢?据我现在看到的资料来看,就是方便,使用矩阵运算之后,可以将多种变换统一成矩阵的乘法运算,方便计算机流水线式处理。 最后回答一下第二个问题:
2.为什么硬件加速要使用transform,以及为什么硬件加速会快? 第一点是因为css的3d transform属性使用在一个元素上该元素会被提升成一个单独的layer,在一个单独的layer上使用一些变换可以直接跳过浏览器渲染的一般流程layout,paint,直接在计算结束之后进行一次composite ,这是快的第一点, 第二点是因为使用transform变换的元素其运算发生在gpu上,而gpu的多核在处理并发运算的时候本身就要比cpu快 基本是这样.
最后分享一个矩阵的乘法运算,可以验证一下css transform相关的矩阵运算 。
// 矩阵相乘
function multipy(a,b){
let r = a.length;
let col = a[0].length;
let result = [];
for( let i = 0; i < r; i++ ){
let row = a[i];
result[i] = [];
for( let j = 0; j < r; j++){
let count = 0;
for( let x = 0;x < col; x++ ){
let item1 = row[x];
let item2 = b[x][j]
count += (item1*item2)
}
result[i].push(count)
}
}
return result;
}
const deg45 = Math.PI/4;
后记 image-preview是一款移动端图片浏览器插件, 在这个分支得提交中 将变换矩阵直接应用到了实际应用中,基本得图形变换已经全部由变换矩阵实现.
最后此篇关于矩阵的乘法运算与css的3d变换(transform)的文章就讲到这里了,如果你想了解更多关于矩阵的乘法运算与css的3d变换(transform)的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
为什么 (defun boolimplies (a b) (or (not a) b)) if called as(boolimplies 'a 'b) 返回 B? 即使我不使用任何 boolean
这个问题已经有答案了: Are there builtin functions for elementwise boolean operators over boolean lists? (5 个回答
我正在寻求帮助以使以下功能看起来更清晰。我觉得我可以通过使用更少的代码行来实现同样的目标。 标题看起来一定很困惑,所以让我详细说明一下。我创建了一个函数,它接受用户输入(即 72+5),将字符串拆分为
我正在学习 C++ 并尝试为矩阵编写一个 C++ 类,我在其中将矩阵存储为一维 C 数组。为此,我定义了一个 element成员函数根据矩阵元素在数组中的位置访问矩阵元素。然后我重载了 class
我正在学习 C++ 并尝试为矩阵编写一个 C++ 类,我在其中将矩阵存储为一维 C 数组。为此,我定义了一个 element成员函数根据矩阵元素在数组中的位置访问矩阵元素。然后我重载了 class
伙计们,以下内容不起作用 函数返回 true,变量返回 false,但它不会进入 when 子句。我尝试像这样放大括号 但是当我将变量的值设置为 true 并将上面的代码更改为 它进入w
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 9 年前。 Improve th
我是原生 C 语言的新手,但我没有看到错误。 我尝试在这种情况下使用 if 操作: #define PAGE_A 0 #define PAGE_B 1 int pageID = 0; if (page
我正在从事一个项目,让用户鼠标滚轮移动并知道它向上或向下滚动。在我的代码中,我可以上下移动。但我想将 Action 保存到一个字符串中。例如,如果用户向上向上向下滚动'mhmh' 显示返回“UUD”但
我有一个 MySQL 表 payment我在其中存储客户的所有付款相关数据。表字段为:fileNo , clientName , billNo , billAmount , status 。我想构建一
我的表架构如下: +------+-------+-------+
我有这个(顺便说一句,我刚刚开始学习): #include #include using namespace std; int main() { string mystr; cout << "We
我正在用 bash 构建一个用于 Linux (SLES 11SP3) 的脚本。我想通过使用以下语法查找它的 pid 来检查某个进程是否存在: pid="$(ps -ef | grep -v grep
我有一个包含两列的表格; CREATE TABLE IF NOT EXISTS `QUESTION_CATEGORY_RELATION` ( `question_id` int(16) NOT N
我对 Python 如何计算 bool 语句感到困惑。 例如 False and 2 or 3 返回 3 这是如何评估的?我认为 Python 首先会查看“False and 2”,甚至不查看“or
这个问题在这里已经有了答案: 12 年前关闭。 这可能是非常基本的......但我似乎不明白: 如何 (2 & 1) = 0 (3 & 1) = 1 (4 & 1) = 0 等等.. 上面的这种模式似
无论如何在Haskell中定义如下函数? or True True = True or True undefined = True or True False
如您所知,TCL 有一些数学函数,例如 罪 , 因 , 和 假设 在 中调用的expr 带有 的命令() 大括号如下: puts [expr sin(1.57)] 现在如何使用 TCL 添加功能 li
让我们考虑两个数组列表。 ArrayList list1 = new ArrayList(); list1.add(1); list1.add(2); list1.add(3); ArrayList
我想包含和排除使用AND和OR的专业知识,包括与AND和OR操作正常工作。但是,当将排除专家与AND和OR一起使用时,返回与3相同的结果计数。我使用的是1.4版 Elasticsearch 。帮助我解
我是一名优秀的程序员,十分优秀!