美文网首页辅助资料unity
Unity中的空间转换矩阵构造

Unity中的空间转换矩阵构造

作者: 最怕认真 | 来源:发表于2019-05-29 16:58 被阅读7次
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    
    public class MatrixPoint : MonoBehaviour {
    
        Matrix4x4 CreateMatrix()
        {
            Matrix4x4 matrix = new Matrix4x4();
            matrix.SetRow(0, new Vector4(transform.right.x, transform.up.x, transform.forward.x, transform.position.x));
            matrix.SetRow(1, new Vector4(transform.right.y, transform.up.y, transform.forward.y, transform.position.y));
            matrix.SetRow(2, new Vector4(transform.right.z, transform.up.z, transform.forward.z, transform.position.z));
            matrix.SetRow(3, new Vector4(0, 0, 0, 1));
            return matrix;
        }
    
        List<Vector3> TestPoints()
        {
            var p1 = Vector3.zero;
            var p2 = p1 + Vector3.right;
            var p3 = p2 + Vector3.up;
            var p4 = p1 + Vector3.up;
            List<Vector3> points = new List<Vector3>()
            {
                p1,p2,p3,p4
            };
            return points;
        }
    
        void DrawPoints(List<Vector3> points,Color color)
        {
            Gizmos.color = color;
            for (int i = 0; i < points.Count; i++)
            {
                Gizmos.DrawSphere(points[i], 0.01f);
                if (i != points.Count - 1)
                    Gizmos.DrawLine(points[i], points[i + 1]);
            }
        }
    
        private void OnDrawGizmos()
        {
           
                var matrix = CreateMatrix();
                var testPoints = TestPoints();
                DrawPoints(testPoints, Color.red);
    
                List<Vector3> newPoints = new List<Vector3>();
                testPoints.ForEach(pt => newPoints.Add(matrix.MultiplyPoint(pt)));
    
                DrawPoints(newPoints, Color.blue);
           
        }
    
    }
    
    
    image.png

    在场景中创建一个物体,然后将脚本挂载到该物体上,就会将世界坐标系下的点转换到物体本地坐标系下的位置。


    这里主要的知识点是如何构造这个变化矩阵,也就是这段代码

     Matrix4x4 CreateMatrix()
        {
            Matrix4x4 matrix = new Matrix4x4();
            matrix.SetRow(0, new Vector4(transform.right.x, transform.up.x, transform.forward.x, transform.position.x));
            matrix.SetRow(1, new Vector4(transform.right.y, transform.up.y, transform.forward.y, transform.position.y));
            matrix.SetRow(2, new Vector4(transform.right.z, transform.up.z, transform.forward.z, transform.position.z));
            matrix.SetRow(3, new Vector4(0, 0, 0, 1));
            return matrix;
        }
    

    关于unity中矩阵的图文讲解,这里有一篇文章很不错,可以查看,本文也借用了其中一些图片。

    我们先回想下矩阵的计算规则


    image.png

    图示的非常清楚了,就是用前矩阵的和后矩阵的对应元素相乘然后累加。

    那么为什么空间坐标的转换能用矩阵来表示呢?又应该如何表示呢?

    image.png

    我们先以二维空间的坐标转换为例。
    wi,wj为w坐标系下的一组基,也就是我们所说的x和y坐标
    li,lj为l坐标系下的一组基
    在w坐标系下的wp,要转换到L坐标系下,并用w坐标系下的wi和wj来表示它。
    很容易理解的是
    lp = Lo + (u*Li,v*Lj)
    我们把后半部分(uLi,vLj)换个写法
    (u*Li,v*Lj) = u*(Li.x,Li.y),v*(Lj.x,Lj.y)=(u*Li.x+v*Lj.x , u*Li.y+v*Lj.y)
    这个写法,似乎不太直观,不如这样,我们搞点新花样
    把uv拿出来写成一列,变成这样

    image.png
    然后逗号左边的u*Li.x+v*Lj.x除去uv后剩下的Li.x+Lj.x也搞个新花样,变成这样
    image.png
    然后再做个规定,下面图片作用上面图片,就按照u*Li.x+v*Lj.x的规则来计算,没错,这就是矩阵的由来(我猜想的,史称认真的猜想)
    那么逗号左右加起来应该是
    image.png
    整个lp-Lo就可以表示成
    图3.png
    那么lp就应该等于Lo+图3
    有没有办法把Lo也用这种方法表示下,有的
    image.png

    所以整个lp就可以用图3来表示了。


    那么扩展到3d中

     Matrix4x4 CreateMatrix()
        {
            Matrix4x4 matrix = new Matrix4x4();
            matrix.SetRow(0, new Vector4(transform.right.x, transform.up.x, transform.forward.x, transform.position.x));
            matrix.SetRow(1, new Vector4(transform.right.y, transform.up.y, transform.forward.y, transform.position.y));
            matrix.SetRow(2, new Vector4(transform.right.z, transform.up.z, transform.forward.z, transform.position.z));
            matrix.SetRow(3, new Vector4(0, 0, 0, 1));
            return matrix;
        }
    

    这样来构建矩阵就很顺理成章了


    相关文章

      网友评论

        本文标题:Unity中的空间转换矩阵构造

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