Flutter 45: 图解矩阵变换 Transform 类 (

作者: 阿策神奇 | 来源:发表于2019-05-20 20:52 被阅读19次

          小菜刚学习了 Transform 类,其核心部分在于矩阵变换,而矩阵变换是由 Matrix4 处理的,且无论是如何的平移旋转等操作,根本上还是一个四阶矩阵操作的;接下来小菜学习一下 Matrix4 的基本用法;

    基本构造

    Matrix4(double arg0, ... double arg15)

          Matrix4 默认构造函数由 16 个参数,从左到右从上到下依此排列为一个四阶矩阵;

    transform: Matrix4(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0),
    

    Matrix4.identity()

          Matrix4.identity() 会初始化一个如上的 Matrix4,可在此基础上进行其他矩阵操作;

    transform: Matrix4.identity(),
    transform: Matrix4.identity()..rotateZ(pi / 4),
    

    Matrix4.zero()

          Matrix4.zero() 会初始化一个所有参数值为 0 的空矩阵,在此基础上设置具体的变化矩阵;查看源码所有的初始化都是从 Matrix4.zero() 开始的;

    transform: Matrix4.zero(),
    transform: Matrix4.zero()..setIdentity(),
    

    Matrix4.fromList()

          Matrix4.fromList()List<double> 列表中数据赋值进入 Matrix4(double arg0, ... double arg15) 类似;

    List<double> list = [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0];
    transform: Matrix4.fromList(list),
    

    Matrix4.copy()

          Matrix4.copy() 拷贝一个已有的 Matrix4

    transform: Matrix4.copy(Matrix4.identity()),
    

    Matrix4.columns()

          Matrix4.columns() 由四个 4D 列向量组成;

    import 'package:vector_math/vector_math_64.dart' as v;
    
    transform: Matrix4.columns(
        v.Vector4(1.0, 0.0, 0.0, 0.0),
        v.Vector4(0.0, 1.0, 0.0, 0.0),
        v.Vector4(0.0, 0.0, 1.0, 0.0),
        v.Vector4(0.0, 0.0, 0.0, 1.0)),
    

    Matirx4.inverted()

          Matrix4.inverted() 为逆向矩阵,与原 Matrix4 矩阵相反(矩阵坐标沿着左对角线对称);

    transform: Matrix4.inverted(Matrix4.fromList(list)),
    

    Matrix4.outer()

          Matrix4.outer() 为两个四阶矩阵的合并乘积,注意两个四阶矩阵的先后顺序决定最终合并后的矩阵数组;

    transform: Matrix4.outer(v.Vector4(1.0, 1.0, 1.0, 1.20), v.Vector4.identity()),
    transform: Matrix4.outer(v.Vector4.identity(), v.Vector4(1.0, 1.0, 1.0, 1.20)),
    

    Scale 缩放构造方法

    Matrix4.diagonal3()

          Matrix4.diagonal3() 通过 Vector3 设置缩放矩阵;

    transform: Matrix4.diagonal3(v.Vector3(2.0, 1.0, 1.0)),
    transform: Matrix4.diagonal3(v.Vector3.array([2.0, 2.0, 2.0])),
    

          分析 Vector3 两种构造方法,三个参数分别对应 x / y /z 轴方向缩放;

    factory Vector3(double x, double y, double z) =>
          new Vector3.zero()..setValues(x, y, z);
          
    factory Vector3.array(List<double> array, [int offset = 0]) =>
          new Vector3.zero()..copyFromArray(array, offset);
    

    Matirx4.diagonal3Values()

          Matrix4.diagonal3Values() 类似于将上述构造方法提取出来,直接对三个参数进行缩放赋值;

    transform: Matrix4.diagonal3Values(2.0, 1.0, 1.0),
    

          分析 diagonal3Values 源码,发现 Matrix4 矩阵中坐对角线上的值分别对应 x / y / z 轴方向的缩放;

    factory Matrix4.diagonal3Values(double x, double y, double z) =>
        new Matrix4.zero()
          .._m4storage[15] = 1.0
          .._m4storage[10] = z
          .._m4storage[5] = y
          .._m4storage[0] = x;
    

    Transform 平移构造方法

    Matrix4.translation()

          Matrix4.translation 同样通过 Vector3 构造方法的各参数设置矩阵平移量;水平向右为 x 轴正向,竖直向下为 y 轴正向;

    transform: Matrix4.translation(v.Vector3(10.0, 10.0, 10.0)),
    transform: Matrix4.translation(v.Vector3.array([-10.0, -10.0, 10.0])),
    

    Matrix4.translationValues()

          Matrix4.translationValues() 将矩阵平移量直接赋值展示;

    transform: Matrix4.translationValues(10.0, 10.0, 10.0),
    

          分析 translationValues 源码,Matirx4 四阶矩阵中第四行前三列分别对应 x / y / z 轴方向的偏移量;

    factory Matrix4.translationValues(double x, double y, double z) =>
        new Matrix4.zero()
          ..setIdentity()
          ..setTranslationRaw(x, y, z);
    
    void setTranslationRaw(double x, double y, double z) {
      _m4storage[14] = z;
      _m4storage[13] = y;
      _m4storage[12] = x;
    }
    

    Rotation 旋转构造方法

    Matrix4.rotationX()

          Matrix4.rotationX() 沿 x 轴方向旋转;

    transform: Matrix4.rotationX(pi / 3),
    

          分析源码,四阶矩阵中,index5/6/9/10 共同操作旋转弧度;

    void setRotationX(double radians) {
        final double c = math.cos(radians);
        final double s = math.sin(radians);
        _m4storage[0] = 1.0;  _m4storage[1] = 0.0;
        _m4storage[2] = 0.0;  _m4storage[4] = 0.0;
        _m4storage[5] = c;    _m4storage[6] = s;
        _m4storage[8] = 0.0;  _m4storage[9] = -s;
        _m4storage[10] = c;   _m4storage[3] = 0.0;
        _m4storage[7] = 0.0;  _m4storage[11] = 0.0;
    }
    

    Matrix4.rotationY()

          Matrix4.rotationY() 沿 y 轴方向旋转;

    transform: Matrix4.rotationY(pi / 3),
    

          分析源码,四阶矩阵中,index0/2/8/10 共同操作旋转弧度;

    void setRotationY(double radians) {
        final double c = math.cos(radians);
        final double s = math.sin(radians);
        _m4storage[0] = c;    _m4storage[1] = 0.0;
        _m4storage[2] = -s;   _m4storage[4] = 0.0;
        _m4storage[5] = 1.0;  _m4storage[6] = 0.0;
        _m4storage[8] = s;    _m4storage[9] = 0.0;
        _m4storage[10] = c;   _m4storage[3] = 0.0;
        _m4storage[7] = 0.0;  _m4storage[11] = 0.0;
    }
    

    Matrix4.rotationZ()

          Matrix4.rotationZ() 沿 z 轴方向旋转;

    transform: Matrix4.rotationZ(pi / 3),
    

          分析源码,四阶矩阵中,index0/1/4/5 共同操作旋转弧度;

    void setRotationZ(double radians) {
        final double c = math.cos(radians);
        final double s = math.sin(radians);
        _m4storage[0] = c;
        _m4storage[1] = s;
        _m4storage[2] = 0.0;   _m4storage[4] = -s;
        _m4storage[5] = c;     _m4storage[6] = 0.0;
        _m4storage[8] = 0.0;   _m4storage[9] = 0.0;
        _m4storage[10] = 1.0;  _m4storage[3] = 0.0;
        _m4storage[7] = 0.0;   _m4storage[11] = 0.0;
    }
    

    Skew 斜切

    Matrix4.skewX()

          上一篇博客稍稍介绍过,skewX() 是沿 x 轴方向斜切;

    transform: Matrix4.skewX(pi / 6),
    

          分析源码,四阶矩阵中,第二行第一列元素对应斜切值,即三角函数中 tan

    factory Matrix4.skewX(double alpha) {
        final Matrix4 m = new Matrix4.identity();
        m._m4storage[4] = math.tan(alpha);
        return m;
    }
    

    Matrix4.skewY()

          skewY() 是沿 y 轴方向斜切;

    transform: Matrix4.skewY(pi / 6),
    

          分析源码,四阶矩阵中,第一行第二列元素对应斜切值,即三角函数中 tan

    factory Matrix4.skewY(double beta) {
        final Matrix4 m = new Matrix4.identity();
        m._m4storage[1] = math.tan(beta);
        return m;
    }
    

    Matrix4.skew()

          skew() 是沿 x / y 轴方向斜切;

    transform: Matrix4.skew(pi / 6, pi / 6),
    

          分析源码,四阶矩阵中,将上述两个元素结合展示效果;

    factory Matrix4.skew(double alpha, double beta) {
        final Matrix4 m = new Matrix4.identity();
        m._m4storage[1] = math.tan(beta);
        m._m4storage[4] = math.tan(alpha);
        return m;
    }
    

    组合构造

    Matrix4.compose()

          Matrix4.compose() 可以将平移/旋转/缩放共同组合操作绘制;

    transform: Matrix4.compose(v.Vector3(10.0, 10.0, 10.0), v.Quaternion.random(math.Random(10)), v.Vector3(1.5, 1.0, 1.0)),
    

          分析源码,三个参数分别对应平移量/旋转量/缩放量;旋转量用到了欧拉旋转,小菜还不是很理解,只是在测试中用了 v.Quaternion.random() 的一个构造方法,还有待深入探索;

    factory Matrix4.compose(
            Vector3 translation, Quaternion rotation, Vector3 scale) =>
        new Matrix4.zero()
          ..setFromTranslationRotationScale(translation, rotation, scale);
    

          Matirx4 涉及的范围很广泛,还有很多方法小菜没有研究到,只是尝试了一些常用的构造方法,若有错误的地方请多多指导!

          以下是小菜公众号,欢迎闲来吐槽~


    公众号

    相关文章

      网友评论

        本文标题:Flutter 45: 图解矩阵变换 Transform 类 (

        本文链接:https://www.haomeiwen.com/subject/liaoaqtx.html