0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[Houdni x VEX ] Matrixを使った回転と平行移動

0
Posted at

はじめに

Houdiniを使っているとVEXで回転を記述するためには、QuaternionやMatrixを使う必要がどうしても出てきます。また、平行移動はMatrixの成分を利用して掛け算で行うことができます。

そこでここでは、なるべく簡単にVEXでMatrixを使った回転と平行移動する計算の解説をしていきます。

タイトルなし-2026-03-16 03 23 32(copy)-2026-03-29 19 30 32(copy)-2026-04-02 08 46 21(copy)-2026-04-08 07 14 39(copy)-1.gif

初期状態

Add SOPで原点にポイントを一つ追加した状態から始めます
image.png

VEXで作成したパラメーターについて

詳細

Attribute Wrangleのこのアイコンを押すとパラメータが作れます
image.png


作成したパラメーターはRangeが0~1 なので
度数法の表記ではパラメーターの変化が見てわからないので
必要に応じてRangeを-360~360などに変更してください

image.png

transform Matrixの作成と確認方法

VEX

//run over points

matrix  m = ident(); //単位行列の作成
setpointtransform(0, @ptnum, m); //transform attributeの作成

単位行列はWorld Matrixとも言います
World Matrix とはDCCツール毎に決められた基準の軸のことです

ノードネットワーク

image.png

VIsualize Attribute
Style : Axes
Attribute : transform

まずこれでHoudiniの座標系であるY-Up右手座標と一致したMatrixが作成できたのが確認できます。次から、このtransformを使って回転と平行移動を行っていきます

回転

image.png

quaternion

//run over points

float angle = radians(chf("angle")); //回転用のパラメータを作成し、ラジアン角angleとして使う
matrix3 m = point(0,"transform",@ptnum); //transform matrixを読み込み

//クォーターニオン
vector4 q = quaternion(angle, set(0,1,0));
matrix3 qm = qconvert(q);
m *= qm;

//変換した行列を反映
setpointtransform(0, @ptnum, m); //変化させた transform Mを反映

組み込み関数 rotate

//run over points

float angle = radians(chf("angle")); //回転用のパラメータを作成し、ラジアン角angleとして使う
matrix3 m = point(0,"transform",@ptnum); //transform matrixを読み込み

//回転行列変換
rotate(m, angle, set(0,1,0)); //Y軸を中心にtransform mをパラメーターの値で回転

//変換した行列を反映
setpointtransform(0, @ptnum, m); //変化させた transform Mを反映

quaternionとrotateの比較

結果は同じなので、組み込み関数rotateを使った方が簡単です

quaternion

vector4 q = quaternion(angle, set(0,1,0));
matrix3 qm = qconvert(q);
m *= qm;

rotate

rotate(m, angle, set(0,1,0));

平行移動

image.png

ベクトルの成分分離

//run over points

float translate_x = chf("translate_x"); //平行移動用のパラメータを作成
matrix3 m = point(0,"transform",@ptnum); //transform matrixを読み込み

//vectorの成分分離
vector x_axis = set(m.xx,m.xy,m.xz); //x軸成分のベクトルを抜き出し
vector pos = x_axis*translate_x;  //x軸方向への移動値を作成

//移動を反映
setpointattrib(0,"P",@ptnum , pos);

pretranslate

//run over points

float translate_x = chf("translate_x"); //平行移動用のパラメータを作成
matrix3 m = point(0,"transform",@ptnum); //transform matrixを読み込み

matrix M = m*ident();
pretranslate(M,set(translate_x,0,0));

setpointtransform(0, @ptnum, M);

なぜtranslate()ではなく、pretranslate()なのか?

かなり分かりづらいところです
今回の計算は 回転->平行移動の順

これは行列の掛け算の順にすると
Translate * Rotate なのでpretranslate()で回転のmatrix3 transformの前に移動の計算を割り込ませているイメージです

行列の掛け算の順番は前掛けと覚えておくと良いと思います
スケールまで含めると

やりたいこと : スケール->回転->平行移動なら
行列の掛け算順 : Translate x Rotate x Scale

肩ひじ張らずに
思った通りいかなかったら
計算順を逆にするかpreをつけるかすれば良いんじゃないでしょうか:relaxed:

まとめ

行列はある程度の慣れが必要な計算です

今回はワールドからスタートしましたが
ご自身で回転や移動値が入った状態から意図通りの結果になるか
試してみると良いと思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?