Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

矩阵变换 #5

Open
sundway opened this issue Oct 13, 2016 · 0 comments
Open

矩阵变换 #5

sundway opened this issue Oct 13, 2016 · 0 comments
Assignees

Comments

@sundway
Copy link
Owner

sundway commented Oct 13, 2016

矩阵变化是一个常用的概念,常用多个参数值同时变化,例如《SVG滤镜对图片调色》 这篇文章中对颜色 rgb 的转换就是利用的矩阵变换。同时,CSS、SVG 中的缩放,旋转以及形变底层其实就是依赖的矩阵变换。

2D 中的矩阵变换

首先,看一个比较简单的 2D 中的矩阵转换,明白 2D 的矩阵转换原理之后,3D 的也是同样的思路。现在有一个二维空间的点A(x, y, 1) 坐标为:x, y。需要对这个点进行一个位移变换,那么可以利用一个矩阵可以对左边进行偏移,矩阵为:[1, 0, x', 0, 1, y', 0, 0, 1]。上面的两个矩阵相乘的一个结果就是:(x + x', y + y', 1)。那么,通过设置 x', y' 就可以对坐标 A 进行一个偏移。

缩放

通过上面的矩阵乘法 [a, c, e, b, d, f, 0, 0, 1] 与左边点进行运算,我们可以得到新坐标:(ax + cy + e, bx + dy + f, 1)。根据上面的公式我们可以轻松的发现要实现对坐标进行缩放,只需要让 c, e, b, f 等于 0 即可。那么得到的结果就是 (ax, dy, 1),a 和 d 分别控制对 x, y 的缩放。

旋转

旋转会稍微复杂一点,二维空间的旋转都是绕 z 轴旋转。那么,坐标 A(x, y)旋转之后的坐边关系可以用公式表示:[consθ, sinθ, -sinθ, conθ, 0, 0, 0, 0, 1]。具体的推到公式可以参考这篇文章

3D 中的矩阵变换

理解了 2D 中的矩阵变换之后,3D 中的矩阵变换就很容易理解了,这里可以直接参考 three.js 的源码

scale: function ( v ) {

    var te = this.elements;
    var x = v.x, y = v.y, z = v.z;

    te[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z;
    te[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z;
    te[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z;
    te[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z;

    return this;

}

上面的 this.elements 初始化值是一个不做任何转换的矩阵[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]。所以上面的操作其实就是相当于矩阵重新赋值[v, 0, 0, 0, 0, v, 0, 0, 0, 0, v, 0, 0, 0, 0, v]之后,再与左边进行矩阵运算。接下来看看位移矩阵:

makeTranslation: function ( x, y, z ) {
    this.set(
        1, 0, 0, x,
        0, 1, 0, y,
        0, 0, 1, z,
        0, 0, 0, 1
    );
    return this;
}

很明显的看出这个跟上面解释的 2D 的矩阵变换同理,最后得到的坐标为:x' = x(原坐标) + x, y' = y(原坐标) + y, z' = z(原坐标) + z。旋转的代码就不贴了,分别对应三个轴进行一个三角函数的变换计算出对应的矩阵。

其它

矩阵很方便的时间这些变换,还可以定义很多复杂变换的矩阵。threejs 还封装了很多常见的矩阵,比如绕任意轴进行旋转,如果用简单的变换进行组合会比较复杂。但是理解矩阵之后,就会发现矩阵实现这些效果简单而强大。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant