【Nuke教程】利用Matrix(矩阵)在world space(世界空间)中的转换计算

25 十一月, 2014
261
2

Matrix(矩阵)是非常强大的。尤其是“World matrix”对于“bake annimation”导出到其他软件是非常有用的。在nukepedia里有一个相当不错的教程“Enter the Matrix Knob”。“Camera”节点,“Light”节点,“Axis”节点有“World matrix”按钮。”TransfromGeo”节点却没有这个属性。
有时候我想在”TransformGeo”后利用”World matrix”的数值,他们意味着这是调整位移信息最后的选择,这是一种“在world space内位移信息”。
知识链接:
在数学中,矩阵(Matrix)是指纵横排列的二维数据表格,最早来自于方程组的系数及常数所构成的方阵。这一概念由19世纪英国数学家凯利首先提出。
矩阵是高等代数学中的常见工具,也常见于统计分析等应用数学学科中。在物理学中,矩阵于电路学、力学、光学和量子物理中都有应用;计算机科学中,三维动画制作也需要用到矩阵。 矩阵的运算是数值分析领域的重要问题。将矩阵分解为简单矩阵的组合可以在理论和实际应用上简化矩阵的运算。对一些应用广泛而形式特殊的矩阵,例如稀疏矩阵和准对角矩阵,有特定的快速运算算法。关于矩阵相关理论的发展和应用,请参考矩阵理论。在天体物理、量子力学等领域,也会出现无穷维的矩阵,是矩阵的一种推广。

World matrix1-1

Simple example 简单示例
首先展示利用矩阵 “matrix”来链接”link” 或者 做父子关系”parent”,下面是两个“Axis”的节点普通的连接。

World matrix1-2World matrix1-3 “Axis”节点同时拥有“World”和“Local”两个矩阵matrix 属性。”World matrix”意味着在这个节点的最后位移信息。”Local matrix”意味着那个节点有多少位移“translate”,旋转“rotate”和缩放“scale”信息。
让我们看看这些矩阵”matrix”

World matrix1-4

“Local matrix” 和”World matrix在”Axis_parent”节点中有相同的数值。而在”Axis_child” 两个值不一样。在这种情况下,”Axis_parent”是一种根“root”或上层“top”节点,所以它们必须是一样的,”Axis_child”会受到 “Axis_parent”的影响。这就是为什么在“Axis_child”中的数值是不同的。
让我们用python来计算 “Axis_child”这个”World matrix”。我们能够与matix相乘得到。
相乘的指令必须 是”the matrix of child * the matrix of parent“. 这是非常重要的,所以它可以被写入。。。。。。
World matrix of Axis_child = Local matrix of Axis_child * World matrix of Axis_parent

在python可以这样写

import math
mAxisParent = nuke.math.Matrix4()
mAxisChild = nuke.math.Matrix4()

for i in range(0,16):
mAxisParent[i] = nuke.toNode("Axis_parent")['matrix'].valueAt(nuke.frame())[i]
mAxisChild[i] = nuke.toNode("Axis_child")['matrix'].valueAt(nuke.frame())[i]

print mAxisChild * mAxisParent

#result:
{1.63506, -0.761793, 0.863863, 52.2646, -1.07639, -0.47688, 1.61678, 167.706, -0.409846, -1.78669, -0.799856, 175.59, 0, 0, 0, 1}

让我们来比较一下在”Axis_local”中的”World matrix”

World matrix1-5

{1.63506, -0.761793, 0.863863, 52.2646, -1.07639, -0.47688, 1.61678, 167.706, -0.409846, -1.78669, -0.799856, 175.59, 0, 0, 0, 1}

矩阵与”TransformGeo”一起作用
“TransformGeo”节点没有”World matrix”按钮。所以我们不能如此简单地在world space内得到转换。 我们能够做出某种复杂的组合。

World matrix1-6

World matrix1-7

World matrix1-8

父子之间的关系就像这样。

乘法的指令是:
The transformation of “Sphere” = matrix of “TranformGeoA” * matrix of “AxisA” * matrix of “TranformGeoB” * matrix of “AxisB”

在python中就像这样

import math

mAxisA = nuke.math.Matrix4()
mAxisB = nuke.math.Matrix4()
mTransformGeoA = nuke.math.Matrix4()
mTransformGeoB = nuke.math.Matrix4()

mResult = nuke.math.Matrix4()

for i in range(0,16):
mAxisA[i] = nuke.toNode("AxisA")['matrix'].valueAt(nuke.frame())[i]
mAxisB[i] = nuke.toNode("AxisB")['matrix'].valueAt(nuke.frame())[i]
mTransformGeoA[i] = nuke.toNode("TransformGeoA")['matrix'].valueAt(nuke.frame())[i]
mTransformGeoB[i] = nuke.toNode("TransformGeoB")['matrix'].valueAt(nuke.frame())[i]

mResult = mTransformGeoA * mAxisA * mTransformGeoB * mAxisB

AxisResult = nuke.createNode("Axis")
AxisResult.setName("Axis_result")

AxisResult['useMatrix'].setValue(True)

for i in range(0,16):
AxisResult['matrix'].setValueAt(mResult[i], nuke.frame(), i)

#Result

此代码将”Axis” 命名为Axis_result”,具有此乘法的答案。
Once excute this code,  we can get “Axis_result” which has same transformation of “Sphere1″
一旦执行该代码,终究我们能够得到”Axis_result”,与”Sphere1有相同的转换。

World matrix1-9

有效方法
我们不仅仅能够得到matrix,同时也能得到简单的位移“translate”、旋转“rotate”和缩放“scale”信息。
translationOnly(), rotationOnly() and scaleOnly() 这些函数能够给我们提供这些数值
translationOnly(), rotationOnly() and scaleOnly()

在python中使用

import math

mResult = nuke.math.Matrix4()

for i in range(0,16):
mResult[i] = nuke.toNode("Axis_result")['matrix'].valueAt(nuke.frame())[i]

mResult.transpose()

mTranslate = nuke.math.Matrix4(mResult)
mTranslate.translationOnly()
mRotate = nuke.math.Matrix4(mResult)
mRotate.rotationOnly()
mScale = nuke.math.Matrix4(mResult)
mScale.scaleOnly()

translate = (mTranslate[12], mTranslate[13], mTranslate[14])
rotateRad = mRotate.rotationsZXY()
rotate = (math.degrees(rotateRad[0]), math.degrees(rotateRad[1]), math.degrees(rotateRad[2]))
scale = (mScale.xAxis().x, mScale.yAxis().y, mScale.zAxis().z)

print tanslate, rotate, scale

#result
(-12.173063278198242, 47.61678695678711, 14.971372604370117) (31.856541873883902, -121.69981885766695, 118.28480623493063) (1.4999998807907104, 1.4999998807907104, 1.4999998807907104)