マトリックス変換のサンプルは、hou.Geometry.transformPrimsとhou.Matrix4.explodeを参照してください。
関数 ¶
buildTranslate(tx, ty, tz)
→ hou.Matrix4
移動だけを含んだトランスフォームマトリックスを返します。 この結果と他のトランスフォームマトリックスを乗算することで、より複雑なトランスフォームを構築することができます。
x,y,zの3つのfloat値、3つのfloatのシーケンス、hou.Vector3を指定することができます。
forward_z = hou.hmath.buildTranslate(0, 0, 1) forward_x = hou.hmath.buildTranslate(hou.Vector3(1, 0, 0))
buildRotateAboutAxis(axis, angle_in_deg)
→ hou.Matrix4
軸と回転量を指定することで、回転だけを含んだトランスフォームマトリックスを返します。 この結果と他のトランスフォームマトリックスを乗算することで、より複雑なトランスフォームを構築することができます。
axis
回転軸を定義したhou.Vector3法線。例えば、hou.Vector3(0, 1, 1)
はプラスのYとZの斜め方向を向いた回転軸になります。
angle_in_deg
その回転軸で回転させる角度(度)。
turn_45_around_yz = hou.hmath.buildRotateAboutAxis(hou.Vector3(0, 1, 1), 45)
オイラー角をそれに相当する軸と角度に変換したいのであれば、以下のコードを使用することができます:
def extractAxisAndAngleFromRotateMatrix(m): '''マトリックスを指定すると、軸と角度を含んだ(Vector3, float)を返します。 詳細は、Wikipediaの回転表現のページを参照してください。''' import math acos_input = (m.at(0, 0) + m.at(1, 1) + m.at(2, 2) - 1.0) * 0.5 if acos_input < -1.0 or acos_input > 1.0: return None angle = math.acos(acos_input) if angle >= -1e-6 and angle <= 1e-6: # 回転はありません。任意の軸と0の回転を選択します。 return hou.Vector3(1, 0, 0), 0.0 inv_sin = 1.0 / (2.0 * math.sin(angle)) axis = hou.Vector3( (m.at(1, 2) - m.at(2, 1)) * inv_sin, (m.at(2, 0) - m.at(0, 2)) * inv_sin, (m.at(0, 1) - m.at(1, 0)) * inv_sin) return axis, hou.hmath.radToDeg(angle) def eulerToAxisAndAngle(angles): return extractAxisAndAngleFromRotateMatrix(hou.hmath.buildRotate(angles))
詳細は、 Wikipediaの軸角度のページ と 回転表現のページ を参照してください。
buildRotateZToAxis(axis)
→ hou.Matrix4
Z軸を、指定した軸に回転させるトランスフォームマトリックスを返します。 この結果と他のトランスフォームマトリックスで乗算することで、より複雑なトランスフォームを構築することができます。
axis
Z軸を回転させて向かせる軸を定義したhou.Vector3。
rotate_z_to_x = hou.hmath.buildRotateZToAxis(hou.Vector3(1, 0, 0))
取得される回転は、最短の回転になります。 ゴールベクトルがZ軸と反対の方向を向いていた場合、勝ってとはいえ整合性の取れたマイナスZ軸にマップされた回転が取得されます。
buildRotate(rx, ry, rz, order="xyz")
→ hou.Matrix4
オイラー角度のシーケンスを指定すると、回転だけを含んだトランスフォームマトリックスを返します。 この結果と他のトランスフォームマトリックスを乗算することで、より複雑なトランスフォームを構築することができます。
x,y,zの3つのfloat値、3つのfloatのシーケンス、hou.Vector3を指定することができます。
xform1 = hou.hmath.buildRotate(45, 45, 0) xform2 = hou.hmath.buildRotate(hou.Vector3(90, 0, 90))
order
x
,y
,z
の文字の順列を含んだ文字列。これは回転順を制御します。
詳細は、 Wikipediaのオイラー角のページ を参照してください。
buildScale(sx, sy, sz)
→ hou.Matrix4
スケールのみを含んだトランスフォームマトリックスを返します。 この結果と他のトランスフォームマトリックスを乗算することで、より複雑なトランスフォームを構築することができます。
x,y,zの3つのfloat値、3つのfloatのシーケンス、hou.Vector3を指定することができます。均一スケールを適用するなら、x,y,zに同じ値を使用してください。
stretch = hou.hmath.buildScale(2, 1, 1) uniform = hou.hmath.buildScale(hou.Vector3(2, 2, 2))
サンプルは、hou.Geometry.createNURBSSurfaceを参照してください。
buildShear(shearx, sheary, shearz)
→ hou.Matrix4
シアーのみを含んだトランスフォームマトリックスを返します。 この結果と他のトランスフォームマトリックスを乗算することで、より複雑なトランスフォームを構築することができます。
x,y,zの3つのfloat値、3つのfloatのシーケンス、hou.Vector3を指定することができます。
詳細は、 Wikipediaのシアーマトリックスのページ を参照してください。
buildTransform(values_dict, transform_order="srt", rotate_order="xyz")
→ hou.Matrix4
(例えばhou.Matrix4.explodeが生成する)文字列からベクトルへのマッピングを含んだ辞書を受け取り、hou.Matrix4トランスフォームを返します。 この結果を使用することで、マトリックスを展開して、いくつかのコンポーネントを変更してから、それを再度マトリックスに戻したり、いくつかのコンポーネントを使ってゼロからマトリックスを生成することができます。
この辞書には、次のキーのどれかを含めることができます: translate
, rotate
, scale
, shear
, pivot
, pivot_rotate
。その値には、hou.Vector3オブジェクトまたは3タプルのfloatを指定することができます。
transform_order
s
,r
,t
の文字の順列を含んだ文字列。
回転、スケール、移動の結果は、あなたが行なったそれらの処理順に関係なく、この文字列にはその順序を指定します。
rotate_order
x
,y
,z
の文字の順列を含んだ文字列。
これは、座標軸を基準に実行される回転順を決めます。
これは、常に"xyz"
順で適用される“pivot_rotate”角度には適用されません。
この関数は、以下のように再実装することができます:
def buildTransform(values_dict, transform_order="srt", rotate_order="xyz"): # トランスフォームと回転順で展開された戻り値を受け取り、 # 元のマトリックスを再構築します。 result = hou.hmath.identityTransform() for operation_type in transform_order: if operation_type == "t": result *= hou.hmath.buildTranslate(values_dict["translate"]) elif operation_type == "s": result *= hou.hmath.buildScale(values_dict["scale"]) if "shear" in values_dict: result *= hou.hmath.buildShear(values_dict["shear"]) elif operation_type == "r": result *= hou.hmath.buildRotate(values_dict["rotate"], rotate_order) else: raise ValueError("Invalid transform order") return result
combineLocalTransform(local, world, parent_local=None, mode=hou.scaleInheritanceMode.Default)
→ hou.Matrix4
ローカルトランスフォームと親ワールドトランスフォームを渡すと、新しいワールドトランスフォームを返します。
extractLocalTransform(world, parent_world, parent_local, mode=hou.scaleInheritanceMode.Default, effective_local=None)
→ hou.Matrix4
ワールドトランスフォームと新しい親トランスフォームを渡すと、新しいローカルトランスフォームを返します。
effective_local
を指定すると、mode
を考慮した実質的なローカルトランスフォームになるように修正されたhou.Matrix4を返します。
identityTransform()
→ hou.Matrix4
単位行列を返します。これはhou.Matrix4(1)
と同じなのですが、コードの可読性を良くすることができます。
>>> hou.hmath.identityTransform() <hou.Matrix4 [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]>
hou.Matrix4を参照してください。
degToRad(degrees)
→ float
度の値を指定すると、ラジアンの値が返されます。
この関数は、degrees * math.pi / 180.0
と等価です。
radToDeg(radians)
→ double
ラジアンの値を指定すると、度の値が返されます。
この関数は、radians * 180.0 / math.pi
と等価です。
clamp(value, min, max)
→ float
min
からmax
の範囲にクランプされた値を返します。
hou.hmath.wrapも参照してください。この関数は、エクスプレッションで値が指定した範囲外にならないようにするのに役に立ちます。
wrap(value, min, max)
この結果の値は常に指定した最小/最大値の範囲内になるという点では、hou.hmath.clamp関数と同様です。 しかし、この関数は、連続的にパラメータ値を増減させる時にノコギリ波を作成します。
sign(value)
→ int
value
がプラスなら1.0、マイナスなら-1.0、0なら0.0を返します。
これは、Pythonのビルトインであるcmp
関数でfloat(cmp(value, 0))
とすることでも同じことができます。
smooth(value, min, max)
→ float
値と範囲を受け取り、0から1の範囲を滑らかに補間した値を返します。
value
がmin
未満の時、戻り値は0です。
value
がmax
より大きい時、戻り値は1です。
>>> hou.hmath.smooth(5, 0, 20) 0.15625 >>> hou.hmath.smooth(10, 0, 20) 0.5 >>> hou.hmath.smooth(15, 0, 20) 0.84375
# 色々な位置にジオメトリオブジェクトを配置することで、この関数の出力を可視化します。 def createSpheres(num_spheres=40): for i in range(num_spheres): sphere = hou.node("/obj").createNode("geo").createNode("sphere") sphere.parmTuple("rad").set((0.1, 0.1, 0.1)) sphere.setDisplayFlag(True) # 0から5までの間の値を指定すると、0から3の範囲でsmoothをコールします。 # そして、その結果のY値は0から1の間になります。 x = 5.0 * i / num_spheres y = hou.hmath.smooth(x, 0, 3) sphere.parent().setParmTransform(hou.hmath.buildTranslate((x, y, 0)))
fit(value, old_min, old_max, new_min, new_max)
→ float
old_min
からold_max
までの間でのvalue
の相対位置からnew_min
とnew_max
の間の値を返します。
その値がold_min
からold_max
までの範囲外であれば、新しい範囲にクランプされます。
>>> hou.hmath.fit(3, 1, 4, 5, 20) 15.0
fit01(value, new_min, new_max)
→ float
0から1までの間でのvalue
の相対位置からnew_min
とnew_max
の間の値を返します。
その値が0から1までの範囲外であれば、新しい範囲にクランプされます。
この関数は、hou.hmath.fit(value, 0.0, 1.0, new_min, new_max)
のショートカットです。
fit10(value, new_min, new_max)
→ float
1から0までの間でのvalue
の相対位置からnew_min
とnew_max
の間の値を返します。
その値が1から0までの範囲外であれば、新しい範囲にクランプされます。
この関数は、hou.hmath.fit(value, 1.0, 0.0, new_min, new_max)
のショートカットです。
fit11(value, new_min, new_max)
→ float
-1から1までの間でのvalue
の相対位置からnew_min
とnew_max
の間の値を返します。
その値が-1から1までの範囲外であれば、新しい範囲にクランプされます。
この関数は、hou.hmath.fit(value, -1.0, 1.0, new_min, new_max)
のショートカットです。
rand(seed)
→ float
0以上1未満の擬似乱数を返します。同じseed
を使用すると、常に同じ結果になります。
noise1d(pos)
→ float
N次元空間での位置を表現した1から4個のfloatのシーケンスを指定すると、1次元ノイズに相当する単一floatを返します。
この関数は、VEXのnoise関数の出力と同じです。
noise3d(pos)
→ hou.Vector3
N次元空間での位置を表現した1から4個のfloatのシーケンスを指定すると、指定した位置でのベクトルノイズを表現したhou.Vector3オブジェクトを返します。
この関数は、VEXのnoise関数の出力と同じです。
orient2d(pa, pb, point)
→ float
pa
とpb
で定義された直線に対して2dポイントの適応実辺性テストを実行します。
この実装の詳細は、http://www.cs.cmu.edu/~quake/robust.htmlを参照してください。
orient3d(pa, pb, pc, point)
→ float
pa
, pb
, pc
で定義された平面に対して3dポイントの適応実面性テストを実行します。
この実装の詳細は、http://www.cs.cmu.edu/~quake/robust.htmlを参照してください。
inCircle(pa, pb, pc, point)
→ float
pa
, pb
, pc
で定義された円に対して2dポイントの適応実内側性テストを実行します。
pa
, pb
, pc
の順序は、内側ポイントからプラス値を得るには、必ず反時計回りでなければなりません。
この実装の詳細は、http://www.cs.cmu.edu/~quake/robust.htmlを参照してください。
inSphere(pa, pb, pc, pd, point)
→ float
pa
, pb
, pc
, pd
で定義された球に対して3dポイントの適応実内側性テストを実行します。
球を定義した4つのポイントの向きに一貫性がなければ、その結果の符号が反転します。
この実装の詳細は、http://www.cs.cmu.edu/~quake/robust.htmlを参照してください。
intersectPlane(plane_point, plane_normal, line_origin, line_dir)
→ hou.Vector3
原点と法線ベクトル(plane_point
とplane_normal
)で定義された平面、原点と方向(line_origin
とline_dir
)で定義されたラインを受け取り、そのラインと平面との交点のXYZ座標を表現したhou.Vector3値を返します。すべての引数には、hou.Vector3を指定しなければなりません。
hou.hmath.intersectPlane( hou.Vector3(0, 0, 0), hou.Vector3(0, 1, 0), hou.Vector3(0.212, 1.56, 0), hou.Vector3(0, 0.62, -0.34) ) # -> hou.Vector3(0.212, -1.19209e-07, 0.855484)
(このラインは、原点からline_dir
の両方向に伸びることに注意してください。つまり、line_dir
が平面から遠くの方へ向いていたとしても、その原点の“背後”の交点が取得されます。)
hou.hmath.intersectPlane( hou.Vector3(0, 0, 0), hou.Vector3(0, 1, 0), # 地面 hou.Vector3(0, 1, 0), hou.Vector3(0, 1, 0) # 地面から1ユニット上を起点とした上向きのライン ) # -> hou.Vector3(0, 0, 0)
この関数は、ラインと平面が平行な場合、または、line_dir
の長さがゼロの場合、さらには、ラインが数学的に平行でないものの、その解がほぼ-100000, -100000
から100000, 100000
の矩形外になるくらいに“十分に平行”な場合には、例外を引き起こします。
slerpTransforms( xforms, input_weights, normalize_weights, slerp_method, slerp_flip_method)
→ hou.Matrix4
別々のクォータニオンに分解することで、トランスフォームを球状にブレンドします。
xforms
は、ブレンドするhou.Matrix4トランスフォームの配列です。
input_weights
は、xforms
と同じサイズのfloat配列です。
normalize_weights
をTrueに設定すると、入力のウェイトが正規化されます。
slerp_method
を0に設定すると、クォータニオンの正規化された線形補間を使ってブレンドすることができ、1に設定すると反復法を使用してブレンドすることができます。
slerp_flip_method
では、slerpがブレンド時の整合性を確保するための反転メソッドを定義します。
これを0に設定すると、1番目のクォータニオンの半球が使用され、1に設定するとNLERP使用時にそれぞれ隣接するクォータニオンを比較します。