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);
}
}

在场景中创建一个物体,然后将脚本挂载到该物体上,就会将世界坐标系下的点转换到物体本地坐标系下的位置。
这里主要的知识点是如何构造这个变化矩阵,也就是这段代码
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中矩阵的图文讲解,这里有一篇文章很不错,可以查看,本文也借用了其中一些图片。
我们先回想下矩阵的计算规则

图示的非常清楚了,就是用前矩阵的行和后矩阵的列对应元素相乘然后累加。
那么为什么空间坐标的转换能用矩阵来表示呢?又应该如何表示呢?

我们先以二维空间的坐标转换为例。
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拿出来写成一列,变成这样

然后逗号左边的
u*Li.x+v*Lj.x
除去uv后剩下的Li.x+Lj.x
也搞个新花样,变成这样
然后再做个规定,下面图片作用上面图片,就按照
u*Li.x+v*Lj.x
的规则来计算,没错,这就是矩阵的由来(我猜想的,史称认真的猜想)那么逗号左右加起来应该是

整个lp-Lo就可以表示成

那么lp就应该等于Lo+图3
有没有办法把Lo也用这种方法表示下,有的

所以整个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;
}
这样来构建矩阵就很顺理成章了
网友评论