Unity中矩阵的平移、旋转、缩放

http://gad.qq.com/article/detail/33543

创建项目

 

首先创建一个Unity工程,克森把他命名为“Matrix of China”(中国的矩阵),基本配置如下图所示:

Unity中矩阵的平移、旋转、缩放_第1张图片

 

为了便于查找,让我们在 Assets 目录下新建三个文件夹,分别命名为“Scripts”、“Shader”、“Materials”,这个不用解释,大伙们都看得懂吧。如下图所示:

 

 

接下来再 Scripts 文件夹里创建一个 C# 脚本,命名为“Triangle”,该脚本用于创建一个简单的三角形。然后在 Hierarchy 面板下创建一个空物体,命名为“Triangle”。然后为该物体添加之前创建的“Triangle”脚本,且为该物体添加 Mesh 相关的两个组件,如下图所示:

 

Unity中矩阵的平移、旋转、缩放_第2张图片

 

好,接下来让我们开始码了个码。

 

 

Triangle.cs 

首先让我们看一看完整的代码,然后再一步一步的分析:

 

Unity中矩阵的平移、旋转、缩放_第3张图片

Mesh mesh;
    public Vector3[] vertices;
    public int[] triangle;

    // Use this for initialization
    void Start () {
        //实例化网格
        mesh = new Mesh();
        //分配顶点
        mesh.vertices = vertices;
        //分配三角形顶点的索引
        mesh.triangles = triangle;
        //把预制好的三角形传给对应的组件
        GetComponent().mesh = mesh;
    }

 

 

好,让我们回到 Inspector 面板修改一下“Triangle”脚本的属性,如下图所示:

 

Unity中矩阵的平移、旋转、缩放_第4张图片

 

PS:三角形数组索引必须从0开始,按顺序然后自增 1。且再次强调,三个顶点才能构成一个三角形。

 

好,现在让我们点击 Play 进行测试一下:

 

Unity中矩阵的平移、旋转、缩放_第5张图片

 

Okey,现在我们的三角形算是完成了,接下来开始玩弄它了。

 

脚本中的变换

首先创建一个 C# 脚本,命名为“MyTransform”,并为我们的“Triangle”物体添加此脚本。代码如下:

 

Unity中矩阵的平移、旋转、缩放_第6张图片

public Matrix4x4 matrix;

    // Use this for initialization
    void Start () {
        matrix.SetTRS(transform.position, transform.rotation, transform.localScale);


    }

Unity中矩阵的平移、旋转、缩放_第7张图片

这个就是平移矩阵,其中 (Tx,Ty,Tz) 为平移的方向向量,有些书上是把 Tx、Ty、Tz 放在第四行,当经过克森的测试,Unity的平移矩阵式这样子的。下面我们就做一个简单的测试:

    1.修改“Triangle”的 Position 为(1,2,3)

 

    2.点击 Play 按钮,观察一下 matrix 属性的变化:

 

Unity中矩阵的平移、旋转、缩放_第8张图片

 

    图中画红线的“E03”、“E13”、“E23”正好就是对应上面平移矩阵图中的“Tx”、“Ty”、“Tz”,这说明Unity使用的正是这种方式的平移矩阵。

 

接下来,我们利用平移矩阵做个简单的平移,让我们回到“MyTransform”脚本中添加一些代码:

 

Unity中矩阵的平移、旋转、缩放_第9张图片

public Vector4 v;
    void MyTranslate()
    {
        v = new Vector4(transform.position.x, transform.position.y,
            transform.position.z, 1);
        matrix = Matrix4x4.identity;
        matrix.m03 = 1;
        matrix.m13 = 2;
        matrix.m23 = 3;
        v = matrix*v;
        transform.localScale = v;

    }

PS:记得将“Triangle”物体的 Position 设置为 (0,0,0)。现在让我们点击 Play 查看一下结果对不对:

 

Unity中矩阵的平移、旋转、缩放_第10张图片

 

好了,值是正确的。大家也可以修改一下参数玩玩。至此,平移矩阵大体讲完了,还是有点懵的伙计可以给克森说说。

 

缩放矩阵

这个就是缩放矩阵,其中“Sx”、“Sy”、“Sz”就是各个轴上的缩放因子。缩放矩阵是矩阵表现物体大小变换的矩阵。如果缩放因子小于1,表现为物体缩小;如果大于1,则表现为物体扩大,如果等于1则不发生变化。

 

接下来我们做个简单的测试,把取消之前 Start 函数里的代码,然后修改“Triangle”物体的 Scale 属性为(1,2,3),点击 Play 查看一下结果:

 

Unity中矩阵的平移、旋转、缩放_第11张图片

 

找到对应的各个轴的缩放因子,目前来说结果是正确的了。

 

接下来,我们利用缩放矩阵做个简单的操作,让我们回到“MyTransform”脚本中添加一些代码:

 

Unity中矩阵的平移、旋转、缩放_第12张图片

void MySclae()
    {
        v = new Vector4(transform.localScale.x, transform.localScale.y,
            transform.localScale.z, 1);
        matrix = Matrix4x4.identity;
        matrix.m00 = 1;
        matrix.m11 = 2;
        matrix.m22 = 3;
        v = matrix * v;
        transform.localScale = v;

    }

现在点击 Play 按钮查看一下结果是否正确:

 

Unity中矩阵的平移、旋转、缩放_第13张图片

 

Okey,看来结果是正确的。

 

PS:当各个轴上的缩放因子相等时,即:Sx=Sy=Sz 时,则为均匀缩放。

 

旋转矩阵

Unity中矩阵的平移、旋转、缩放_第14张图片

上图就是所谓的旋转矩阵。在我们的实践中,我就使用沿 x- 轴进行旋转做实践即可。

 

首先还是做个简单的测试,让我们修改一下脚本,然后将物体的 Rotation参数设置为 (45,0,0),最后点击 Play 按钮查看结果,如下图所示:

Unity中矩阵的平移、旋转、缩放_第15张图片

 

在这里我选择了45°角,因为 sin45°和cos45° 的值是相等的(虽然在上图中他们的值不相等,但实际上是相等的,大伙们可以用个 if 语句判断一下),让我们看看结果对不对:

 

Unity中矩阵的平移、旋转、缩放_第16张图片

Okey,看来是正确的。

 

接下来,我们利用旋转矩阵做个简单的操作,让我们回到“MyTransform”脚本中添加一些代码:

 

Unity中矩阵的平移、旋转、缩放_第17张图片

 

public float angle;
    public enum Axle {X,Y,Z };
    public Axle axle;

    void MyRotation()
    {
        matrix = Matrix4x4.identity;
        if (axle == Axle.X)
        {
            matrix.m11 = Mathf.Cos(angle * Mathf.Deg2Rad);
            matrix.m12=-Mathf.Sin(angle * Mathf.Deg2Rad);
            matrix.m21= Mathf.Sin(angle * Mathf.Deg2Rad);
            matrix.m22= Mathf.Cos(angle * Mathf.Deg2Rad);
        }
        if (axle == Axle.Y)
        {
            matrix.m00 = Mathf.Cos(angle * Mathf.Deg2Rad);
            matrix.m02 = Mathf.Sin(angle * Mathf.Deg2Rad);
            matrix.m20 = -Mathf.Sin(angle * Mathf.Deg2Rad);
            matrix.m22 = Mathf.Cos(angle * Mathf.Deg2Rad);
        }
        if (axle == Axle.Z)
        {
            matrix.m00 = Mathf.Cos(angle * Mathf.Deg2Rad);
            matrix.m01 = -Mathf.Sin(angle * Mathf.Deg2Rad);
            matrix.m10 = Mathf.Sin(angle * Mathf.Deg2Rad);
            matrix.m11 = Mathf.Cos(angle * Mathf.Deg2Rad);
        }

        float qw = Mathf.Sqrt(1f + matrix.m00 + matrix.m11
            + matrix.m22) / 2;
        float w = 4 * qw;
        float qx = (matrix.m21 - matrix.m12) / w;
        float qy = (matrix.m02 - matrix.m20) / w;
        float qz = (matrix.m10 - matrix.m01) / w;
        transform.rotation = new Quaternion(qx, qy, qz, qw);


    }

由于图片是拼接的,所有有点别扭

 

All right. 现在让我们回到物体的 Inspector 面板中修改“Angle”参数 和 Axle 选项,然后点击 Play 按钮进行测试即可(在这里克森选择的是,绕 X 轴旋转45°):

 

Unity中矩阵的平移、旋转、缩放_第18张图片

 

Perfect. 和我们预期的效果一样,大伙们可以自行修改参数进行测试一番。

 

最后给大家送上一个小工具,只需传入一个变换矩阵即可帮你完成平移、旋转、缩放的工作,然后把值传给物体的 Position、Rotation、Scale:

 

Unity中矩阵的平移、旋转、缩放_第19张图片

 

接下来用一个例子来演示这个小工具怎么使用。

 

回到我们的场景中,找到“Triangle”物体,在 Inspector 面板中修改“MyTransform”脚本的“Matrix”属性,如下图所示:

 

Unity中矩阵的平移、旋转、缩放_第20张图片

红色箭头代表平移、绿色箭头代表缩放、黄色箭头代表旋转,这个变换矩阵表示的是:物体在X轴上平移3个单位、Y轴上平移4个单位、Z轴上平移5个单位(position (3,4,5));物体绕着X轴旋转90° (Rotation(90,0,0));物体没有缩放 (1,1,1) 。

 

然后回到“MyTransform”脚本的Start函数中调用工具类里的方法完成变换矩阵的各项操作:

 

Unity中矩阵的平移、旋转、缩放_第21张图片

最后点击 Play 按钮查看结果:

 

Unity中矩阵的平移、旋转、缩放_第22张图片

 

Perfect. 看来和我们预期的效果一模一样,大伙们可以自行修改参数进行测试。

你可能感兴趣的:(Unity中矩阵的平移、旋转、缩放)