Houdiniでは4×4マトリックスは、通常では3Dトランスフォームの表現(例えば、回転、スケール、シアー、移動の組み合わせ)に使用されます。 1個のマトリックスは簡潔にトランスフォームを表現し、複数の移動、回転、スケール、シアー、トランスフォーム順序、回転順序の値を使用するよりも 扱いが非常に簡単です。
Houdiniのマトリックスは行優先(row-major)フォーマットで格納され、マトリックスと乗算されるベクトルは、行ベクトルとして扱われます。
そのため、p
がポイントを表現したhou.Vector4で、M
がMatrix4と仮定すると、M*p
ではなく p*M
と記述します。
同様に、p*M1*M2
は、まず最初にp
をM1
でトランスフォームさせて、次にそれをM2
でトランスフォームさせます。
Note
ほとんどの数学表現では、ベクトルやポイントを行ベクトルではなく列ベクトルとして扱います。
数学表現では、A*B*C
(または単にABC
)と記述することで、1番目にC
トランスフォームを適用してからB
、最後にA
のトランスフォームを
適用するといった組み合わせのトランスフォームを表現することが多いです。
しかし、その慣例はHoudiniでは異なります。
Houdiniでそれと同じマトリックスを表現するには、それらのトランスフォームを逆順で連結する必要があります。
そのため、代わりにC'*B'*A'
と記述します。C'
, B'
, A'
は、それぞれC, B, Aの転置行列です。
Vector3やVector4をMatrix4で乗算することができます。 Vector3を乗算する場合、それは4番目のコンポーネントが1のVector4を乗算することと同じになります(hou.Vector3.__mul__を参照してください)。
(ポイントやベクトルとは対照的に)法線をトランスフォームさせるには、そのマトリックスの逆転置行列で乗算する必要があります。例えば、以下を想定します:
p
これは、位置を表現したhou.Vector3オブジェクト(または、p[3]==1
のhou.Vector4)
v
これは、ベクトル(長さを持つ方向で、空間内の位置が不定)を表現したv[3]==0
のhou.Vector4オブジェクト
n
これは、法線を表現したv[3]==0
のhou.Vector4オブジェクト
m
これは、トランスフォームマトリックスを表現したMatrix4オブジェクト
これらは以下のように記述します:
p * m # ポイントをトランスフォームさせる v * m # ベクトルをトランスフォームさせる n * m.inverted().transposed() # 法線をトランスフォームさせる # (m.inverted().transposed()は、数学的にはm.transposed().inverted()と等価です)
以下が具体的なサンプルです:
>>> m = hou.hmath.buildTranslate((1, 1, 2)) >>> m <hou.Matrix4 [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [1, 1, 2, 1]]> >>> p = hou.Vector3(1, 2, 3) >>> p * m <hou.Vector3 [2, 3, 5]>
Houdini Development Kit(HDK)でのVEXとUT_DMatrix4クラスは、どちらも行優先フォーマットでマトリックスを格納します。
メソッド ¶
__init__(values)
新しいMatrix4を返します。パラメータなし(その結果にはすべて0が入ります), float(その結果の対角線の値にそのfloatが入り、それ以外がすべて0が入ります), 16個のfloatのシーケンス、4個のfloatのシーケンスのシーケンス、hou.Matrix3を渡すことができます。
>>> hou.Matrix4() <hou.Matrix4 [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]> >>> hou.Matrix4(1) <hou.Matrix4 [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]> >>> hou.Matrix4((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)) <hou.Matrix4 [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15]]> >>> hou.Matrix4(((0, 1, 2, 3), (4, 5, 6, 7), (8, 9, 10, 11), (12, 13, 14, 15))) <hou.Matrix4 [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15]]> >>> matrix3 = hou.Matrix3((0, 1, 2, 3, 4, 5, 6, 7, 8)) >>> matrix3 <hou.Matrix3 [[0, 1, 2], [3, 4, 5], [6, 7, 8]]> >>> hou.Matrix4(matrix3) <hou.Matrix4 [[0, 1, 2, 0], [3, 4, 5, 0], [6, 7, 8, 0], [0, 0, 0, 1]]>
Houdiniのマトリックスは行優先の順序で格納されるので、そのマトリックスの内容が行でグループ化されます。
at(row, col)
→ float
指定した行と列のマトリックスの値を返します。
その行または列が0から3の範囲でない場合はIndexErrorを引き起こします。 マイナスのインデックスは、最後からのインデックスを取らないことに注意してください。
setAt(row, col, value)
指定した行と列のマトリックスの値を設定します。
その行または列が0から3の範囲でない場合はIndexErrorを引き起こします。 マイナスのインデックスは、最後からのインデックスを取らないことに注意してください。
asTuple()
→ tuple
of float
マトリックスの内容を16個のfloatのタプルとして返します。
asTupleOfTuples()
→ tuple
of tuple
of float
マトリックスの内容を4個のfloatのタプルのタプルとして返します。
setTo(sequence)
このマトリックスの内容を設定します。シーケンスには、16個のfloatまたはそれぞれ4個のfloatを持つ4個のシーケンスを含めることができます。
適切なパラメータ値のサンプルは、hou.Matrix4.__init__を参照してください。
setToIdentity()
このマトリックスを乗法の単位行列に設定し、その対角線が1になります。
そのマトリックスには[[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]
の値が入ります。
hou.hmath.identityTransformまたはhou.Matrix4(1)
を使用して、それらの値を持った新しいマトリックスを構築することができます。
setToZero()
このマトリックスにすべて0が入るように設定します。
hou.Matrix4()
を使用して、すべてが0の新しいマトリックスを構築することができます。
__add__(matrix4)
→ hou.Matrix4
2つのマトリックスを、それぞれ該当するエントリーに加算して、新しいマトリックスを返します。
このメソッドは、m1 + m2
と記述することができます。m1
とm2
はMatrix4オブジェクトです。
__sub__(matrix4)
→ hou.Matrix4
このマトリックスから他のマトリックスを、それぞれ該当するエントリーから減算して、新しいマトリックスを返します。
このメソッドは、m1 - m2
と記述することができます。m1
とm2
はMatrix4オブジェクトです。
__mul__(matrix4_or_scalar)
→ hou.Matrix4
このマトリックスを他のマトリックスやスカラーで乗算し、新しいマトリックスを返します。
このメソッドは、m1 * m2
と記述することができます。m1
とm2
はMatrix4オブジェクトで、m1 * s
ではs
はfloatです。
m1
とm2
がトランスフォームマトリックスで、v
がベクトルなら、
v * m1 * m2
は、v
をm1
でトランスフォームしてから、それをm2
でトランスフォームします。
この順序は、Houdiniのマトリックスが行優先フォーマットで格納されているからであり、典型的な数学的表記で使用されている順番とは逆です。
m1 * v
はHoudiniでは有効なエクスプレッションではないことに注意してください。
詳細は、Matrix4クラスのドキュメントとhou.Vector3.__mul__を参照してください。 その結果での各エレメントの計算方法に関する詳細は、 Wikipediaのマトリックス乗算のページ を参照してください。
preMult(matrix4)
→ hou.Matrix4
matrix4 * self
を返します。__mul__
はself * matrix4
を返します。
これは、マトリックス乗算に可換性がないので、異なった結果になります。
explode(transform_order='srt', rotate_order='xyz', pivot=hou.Vector3(), pivot_rotate=hou.Vector3())
→ dict
of str
to hou.Vector3
キーが'rotate'
, 'scale'
, 'translate'
, 'shear'
で、それらの値がhou.Vector3オブジェクトの辞書を返します。
指定した順序で適用されると、その順序で回転、スケール、(シアー)、移動がこのマトリックスに与えられます。
この回転はオイラー角のセットとして返され、単位は度です。 詳細は、 Wikipediaのオイラー角のページ を参照してください。
transform_order
s
, r
, t
の文字の順列を含んだ文字列。
回転、スケール、移動の結果は、あなたが行なったそれらの処理順に関係なく、この文字列にはその順序を指定します。
例えば、まず最初にx方向に1ユニット移動させ、次にz軸で45度回転させるトランスフォームを想定します。
トランスフォーム順列が'trs'
(移動、回転、スケール)で、移動コンポーネントが(1, 0, 0)とします。
しかし、この同じトランスフォームを構築して、例えば最初にスケールをして、次に回転、最後に移動を行なったとします。
このトランスフォーム順列では、移動コンポーネントは、(1.0 / math.sqrt(2), 1.0 / math.sqrt(2), 0)
となります。
rotate_order
x
, y
, z
の文字の順列を含んだ文字列。
これは、座標軸を基準に実行される回転順を決めます。
pivot
回転とスケールの基準となる位置を含んだVector3。 デフォルトでは、このパラメータは原点に設定されています。
pivot_rotate
x
, y
, z
の軸を基準にした単位が度のオイラー角度を含んだVector3。
ここには、ピボットを基準にしたベース回転を指定します。
これらの角度は常にxyz
順で処理されます。
マトリックスが無効なトランスフォームマトリックス(例えば、行列式がゼロの特異行列)だった場合や、トランスフォーム順が文字列'srt'
の順列でない、
または回転順が文字列'xyz'
の順列でない場合は、hou.OperationFailedを引き起こします。
オイラー角を軸と回転に変換する方法のサンプルは、hou.hmath.buildRotateAboutAxisを参照してください。
サンプルは、hou.ObjNode.setParmTransformを参照してください。 このメソッドは、hou.hmath.buildTransformの逆行列です。 トランスフォームマトリックスの構築に関しては、hou.hmathの他の関数も参照してください。
extractTranslates(transform_order='srt', pivot_rotate=hou.Vector3(), pivot=hou.Vector3())
→ hou.Vector3
self.explode(transform_order, hou.Vector3(), pivot, pivot_rotate)['translate']
のショートカット。
詳細は、hou.Matrix4.explodeを参照してください。
>>> matrix = hou.hmath.buildTranslate(1, 0, 0) * hou.hmath.buildRotate(0, 0, 45) >>> matrix.extractTranslates('trs') <hou.Vector3 [4, 0, 0]> >>> matrix.extractTranslates('srt') <hou.Vector3 [0.707107, 0.707107, 0]>
extractRotates(transform_order='srt', rotate_order='xyz', pivot=hou.Vector3(), pivot_rotate=hou.Vector3())
→ hou.Vector3
self.explode(transform_order, rotate_order, pivot, pivot_rotate)['rotate']
のショートカット。
詳細は、hou.Matrix4.explodeを参照してください。
extractScales(transform_order='srt', pivot=hou.Vector3(), pivot_rotate=hou.Vector3())
→ hou.Vector3
self.explode(transform_order, rotate_order, pivot, pivot_rotate)['scale']
のショートカット。
詳細は、hou.Matrix4.explodeを参照してください。
extractShears(transform_order='srt', pivot=hou.Vector3(), pivot_rotate=hou.Vector3())
→ hou.Vector3
self.explode(transform_order, rotate_order, pivot, pivot_rotate)['shear']
のショートカット。
詳細は、hou.Matrix4.explodeを参照してください。
extractRotationMatrix3()
→ hou.Matrix3
このマトリックスから3×3回転マトリックスを抽出し、それをトランスフォームマトリックスと想定します。 その回転の抽出に失敗、例えば、スケールがある軸でゼロになっていると、この関数は代わりに単位行列を返します。
inverted()
→ hou.Matrix4
このマトリックスの逆行列を返します。
このマトリックスが可逆行列でない場合は、hou.OperationFailedを引き起こします。
可逆行列の場合は、(self * self.inverted())です。
isAlmostEqual(hou.hmath.identityTransform())
はTrueです。
詳細は、 Wikipediaの可逆行列のページ を参照してください。
transposed()
→ hou.Matrix4
このマトリックスの転置行列を返します。その結果は、0 <= i,j <= 3
に対して、self.at(i, j) == self.transposed().at(j, i)
となります。
詳細は、 Wikipediaの転置行列のページ を参照してください。
isAlmostEqual(matrix4, tolerance=0.00001)
→ bool
このマトリックスが許容値内で他のマトリックスと等価かどうか返します。
setToPerspective(zoom, image_aspect=1, pixel_aspect=1, clip_near=0, clip_far=1, window_xmin=0, window_xmax=1, window_ymin=0, window_ymax=1)
指定したパラメータの遠近投影行列をこのマトリックスに設定します。
時折、このズームをFocal(焦点距離)とAperture(絞り)の用語で表現します。
この場合では、zoom = focal/aperture
です。
時折、この画像のアスペクト比をxresとyresの用語で表現します。
この場合では、image_aspect = xres / yres
です。
setToOrthographic(zoom, orthowidth=1, image_aspect=1, pixel_aspect=1, clip_near=0, clip_far=1, window_xmin=0, window_xmax=1, window_ymin=0, window_ymax=1)
指定したパラメータの正投影行列をこのマトリックスに設定します。
時折、このズームをFocal(焦点距離)とAperture(絞り)の用語で表現します。
この場合では、zoom = focal/aperture
です。
時折、この画像のアスペクト比をxresとyresの用語で表現します。
この場合では、image_aspect = xres / yres
です。
See also |