【Unity】数学基础-1-矩阵变换

/**********
*
* 作者 : Quaye
* 时间 : 2018.05.18
*
* 描述 :
* 1.平移变换
* 2.缩放变换
* 2.旋转变换
*
* 注意 :
* 1.约定变换的顺序 : 缩放 -> 旋转 -> 平移;
* 2.Unity旋转使用 Z-X-Y 顺规 : 绕 Z -> 绕 X -> 绕 Y;
**/

using UnityEngine;

public class Scene_1 : MonoBehaviour
{
void Start()
{
m_T();
m_S();
m_R();
}

// ------------ 平移变换 ------------
private void m_T()
{
/****
* 平移矩阵:
*
* | 1 0 0 Tx |
* | 0 1 0 Ty |
* | 0 0 1 Tz |
* | 0 0 0 1 |
*/
var dirVector = new Vector3( 1, 2, 3);
var translateMatri = Matrix4x4.TRS(dirVector, Quaternion.identity, Vector3.one);
Debug.Log( "平移矩阵:\n" + translateMatri.ToString( "F5"));
//
// 下面是利用 Unity API 得出对 平移向量(1,2,3)的 平移矩阵:
//
// 1.00000 0.00000 0.00000 1.00000
// 0.00000 1.00000 0.00000 2.00000
// 0.00000 0.00000 1.00000 3.00000
// 0.00000 0.00000 0.00000 1.00000
//
}




// ------------ 缩放变换 ------------
private void m_S()
{
/****
* 缩放矩阵:
*
* | Sx 0 0 0 |
* | 0 Sy 0 0 |
* | 0 0 Sz 0 |
* | 0 0 0 1 |
*/
var scale = new Vector3( 4, 5, 6);
var scaleMatrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, scale);
Debug.Log( "缩放矩阵:\n" + scaleMatrix.ToString( "F5"));
//
// 下面是利用 Unity API 得出对 缩放向量(4,5,6)的 缩放矩阵:
//
// 4.00000 0.00000 0.00000 0.00000
// 0.00000 5.00000 0.00000 0.00000
// 0.00000 0.00000 6.00000 0.00000
// 0.00000 0.00000 0.00000 1.00000
//
}




// ------------ 旋转变换 ------------
private void m_R()
{
/****
* 旋转矩阵(假设旋转角为 A):
*
* 绕 X 轴
* | 1 0 0 0 |
* | 0 cosA -sinA 0 |
* | 0 sinA cosA 0 |
* | 0 0 0 1 |
*
* 绕 Y 轴
* | cosA 0 sinA 0 |
* | 0 1 0 0 |
* | -sinA 0 cosA 0 |
* | 0 0 0 1 |
*
* 绕 Z 轴
* | cosA -sinA 0 0 |
* | sinA cosA 0 0 |
* | 0 0 1 0 |
* | 0 0 0 1 |
*/
var rotateX = Quaternion.Euler( 30, 0, 0);
var rotateXMatrix = Matrix4x4.TRS(Vector3.zero, rotateX, Vector3.one);
Debug.Log( "绕 X 轴旋转矩阵:\n" + rotateXMatrix.ToString( "F5"));
//
// 下面是利用 Unity API 得出对绕 X 轴旋转 30°的 旋转矩阵:
//
// 1.00000 0.00000 0.00000 0.00000
// 0.00000 0.86603 -0.50000 0.00000
// 0.00000 0.50000 0.86603 0.00000
// 0.00000 0.00000 0.00000 1.00000
//

var rotateY = Quaternion.Euler( 0, 30, 0);
var rotateYMatrix = Matrix4x4.TRS(Vector3.zero, rotateY, Vector3.one);
Debug.Log( "绕 Y 轴旋转矩阵:\n" + rotateYMatrix.ToString( "F5"));
//
// 下面是利用 Unity API 得出对绕 Y 轴旋转 30°的 旋转矩阵:
//
// 0.86603 0.00000 0.50000 0.00000
// 0.00000 1.00000 0.00000 0.00000
// -0.50000 0.00000 0.86603 0.00000
// 0.00000 0.00000 0.00000 1.00000
//

var rotateZ = Quaternion.Euler( 0, 0, 30);
var rotateZMatrix = Matrix4x4.TRS(Vector3.zero, rotateZ, Vector3.one);
Debug.Log( "绕 Z 轴旋转矩阵:\n" + rotateZMatrix.ToString( "F5"));
//
// 下面是利用 Unity API 得出对绕 Z 轴旋转 30°的 旋转矩阵:
//
// 0.86603 -0.50000 0.00000 0.00000
// 0.50000 0.86603 0.00000 0.00000
// 0.00000 0.00000 1.00000 0.00000
// 0.00000 0.00000 0.00000 1.00000
//
m_R_CombinationZYX(); // 如果需要查看复合旋转变换时 启用 此函数
}
private void m_R_CombinationZYX()
{
// 假设将点(1,2,3) 进行旋转变换 X:30°,Y:60°, Z:90°
var position = new Vector3( 1, 2, 3);
var rotate = new Vector3( 30, 60, 90);

// 在 Unity 中这个变换顺序是按照 : 绕z-> 绕x-> 绕y
var unityPoint = GameObject.Find( "Point_Unity");
unityPoint.transform.position = Vector3.zero;
for ( int index = 0; index != unityPoint.transform.childCount; ++index)
{
unityPoint.transform.GetChild(index).transform.localPosition = position;
}
unityPoint.transform.Rotate(rotate);


var pointMatrix = new Vector4(position.x, position.y, position.z, 1);
var RM_X = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(rotate.x, 0, 0), Vector3.one);
var RM_Y = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler( 0, rotate.y, 0), Vector3.one);
var RM_Z = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler( 0, 0, rotate.z), Vector3.one);

// position 手动旋转变换 ZXY
var ZYX_M = RM_Y * RM_X * RM_Z * pointMatrix;
Debug.Log(ZYX_M);
var zxyPoint = GameObject.Find( "Point_ZXY");
zxyPoint.transform.position = new Vector3(ZYX_M.x, ZYX_M.y, ZYX_M.z);
m_DrawPathZXY(position, rotate, Color.blue);

// position 手动旋转变换 YXZ
var YXZ_M = RM_Z * RM_X * RM_Y * pointMatrix;
Debug.Log(YXZ_M);
var yxzPoint = GameObject.Find( "Point_YXZ");
yxzPoint.transform.position = new Vector3(YXZ_M.x, YXZ_M.y, YXZ_M.z);
m_DrawPathYXZ(position, rotate, Color.yellow);

}
// 绘制 ZXY 顺规变换轨迹
private void m_DrawPathZXY( Vector3 pPoint, Vector3 pRotate, Color pZXYColor)
{
var parent = GameObject.Find( "PathParent");
var pV4 = new Vector4(pPoint.x, pPoint.y, pPoint.z, 1);
for ( int index = 0; index != pRotate.z; ++index)
{
pV4 = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler( 0, 0, 1), Vector3.one) * pV4;
var p = GameObject.CreatePrimitive(PrimitiveType.Sphere);
p.transform.SetParent(parent.transform);
p.transform.localScale = Vector3.one * 0.05f;
p.transform.localPosition = new Vector3(pV4.x, pV4.y, pV4.z);
p.GetComponent< Renderer>().material.color = pZXYColor;
}
for ( int index = 0; index != pRotate.x; ++index)
{
pV4 = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler( 1, 0, 0), Vector3.one) * pV4;
var p = GameObject.CreatePrimitive(PrimitiveType.Sphere);
p.transform.SetParent(parent.transform);
p.transform.localScale = Vector3.one * 0.05f;
p.transform.localPosition = new Vector3(pV4.x, pV4.y, pV4.z);
p.GetComponent< Renderer>().material.color = pZXYColor;
}
for ( int index = 0; index != pRotate.y; ++index)
{
pV4 = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler( 0, 1, 0), Vector3.one) * pV4;
var p = GameObject.CreatePrimitive(PrimitiveType.Sphere);
p.transform.SetParent(parent.transform);
p.transform.localScale = Vector3.one * 0.05f;
p.transform.localPosition = new Vector3(pV4.x, pV4.y, pV4.z);
p.GetComponent< Renderer>().material.color = pZXYColor;
}
}
// 绘制 YXZ 顺规变换轨迹
private void m_DrawPathYXZ( Vector3 pPoint, Vector3 pRotate, Color pYXZColor)
{
var parent = GameObject.Find( "PathParent");
var pV4 = new Vector4(pPoint.x, pPoint.y, pPoint.z, 1);
for ( int index = 0; index != pRotate.y; ++index)
{
pV4 = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler( 0, 1, 0), Vector3.one) * pV4;
var p = GameObject.CreatePrimitive(PrimitiveType.Sphere);
p.transform.SetParent(parent.transform);
p.transform.localScale = Vector3.one * 0.05f;
p.transform.localPosition = new Vector3(pV4.x, pV4.y, pV4.z);
p.GetComponent< Renderer>().material.color = pYXZColor;
}
for ( int index = 0; index != pRotate.x; ++index)
{
pV4 = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler( 1, 0, 0), Vector3.one) * pV4;
var p = GameObject.CreatePrimitive(PrimitiveType.Sphere);
p.transform.SetParent(parent.transform);
p.transform.localScale = Vector3.one * 0.05f;
p.transform.localPosition = new Vector3(pV4.x, pV4.y, pV4.z);
p.GetComponent< Renderer>().material.color = pYXZColor;
}
for ( int index = 0; index != pRotate.z; ++index)
{
pV4 = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler( 0, 0, 1), Vector3.one) * pV4;
var p = GameObject.CreatePrimitive(PrimitiveType.Sphere);
p.transform.SetParent(parent.transform);
p.transform.localScale = Vector3.one * 0.05f;
p.transform.localPosition = new Vector3(pV4.x, pV4.y, pV4.z);
p.GetComponent< Renderer>().material.color = pYXZColor;
}
}


// ------------ 复合变换 ------------
private void m_TRS()
{
// 在绝大多数情况下,我们约定变换的顺序
// 1.先缩放
// 2.再旋转
// 3.最后平移
}

}

猜你喜欢

转载自blog.csdn.net/qq_33479009/article/details/80490011