スタジオブロス TECH BLOG

スタジオブロススタッフからの最新ツール情報やチュートリアル・TIPSなどを紹介します

基礎から始める3dsmax/Python(MaxPlus)プログラミング④

前回の続きで、Pythonで回転の設定をやってみましょう。

少しだけ説明しましたが、単純にX,Y,Zの回転の角度を入れればよい、という訳にはいかないようです。

まずは「クォータニオン」です。解りにくいので、こちらのリンクの解説をちょっと見てください。 Unityについての解説ですから、ちょっと難しいので、ページの途中の鳥みたいなキャラが動くGifアニメだけみてください。

tsubakit1.hateblo.jp

簡単にいうとクォータニオンというのは、4つの値を使うので「四元数」ともいい、回転する軸をX,Y,Zで決め、その軸に対して回転角を入れる、という仕組みです。

良く解らない・・・という方が多いのと思うので、3dsmaxで実験しましょう。

適当にティーポットを作ります。

モーション→「コントローラを割り当て」で「回転:オイラーXYZ」を「TCB回転」に変更します。

このように設定されます。

「キー情報」が「XYZ」と「角度」の4項目になります。

実は最初の頃の3dmaxはこれがデフォルトだったのですが、難しいので最近はXYZの角度をそれぞれ入れる「オイラーXYZ」を使うようになりました。

では、この「角度」に90度入れてみましょう。

表示は「ローカル」です。

このようになります。Xを「-1」で角度を90で時計回りに90度回転します。

Xを1にすると、反時計回りに90度回転します。

Zを1にすると、Zを軸に90度回転します。

同様にYを1にすると、Yを軸に90度回転します。

Pythonで回転させるには、基本はこの仕組みを使います。ではプログラムを作ってみましょう。

import MaxPlus as mp
import math
obj = mp.Factory.CreateGeomObject(mp.ClassIds.Teapot) 
node = mp.Factory.CreateNode(obj) 
qtr = mp.AngAxis(1,0,0,math.radians(90))
node.Rotation =mp.Quat(qtr )

これを実行すると、以下のようにXに90度回転してます。

2行目から説明します。

import mathPythonの標準ライブラリでSin,Cos,Logとか数学的な処理をする場合に実行します。

3,4行目は前にもやったティーポットを作る命令なので省略します。

qtr = mp.AngAxis(1,0,0,math.radians(90))

この5行目が初登場で、qtrという変数を作り、それにAngAxisという関数で、クォータニオンの値を作ります。

最初の3つが回転軸を決める値で、1,0,0でX軸に設定しています。

4つ目に角度を入れるのですが、ここはラジアンで代入しないとダメなのです。

学校の数学で教わった・・・けど忘れた!という人が多いと思うので、2行目のmathのPythonの機能で変換します。

それがmath.radians(90)です。

これで90度をラジアンに変換してくれるのです。

math.???というのがmathのライブラリ(外部の関数)を使う方法です。

node.Rotation =mp.Quat(qtr )

6行目でQuat(値)でクォータニオンでXに90度回転しています。

では次の実験です。

import MaxPlus as mp
import math
obj = mp.Factory.CreateGeomObject(mp.ClassIds.Teapot)
obj.ParameterBlock.Radius.Value = 5.0
for i in range(13):
node = mp.Factory.CreateNode(obj)
node.Position = mp.Point3(i*10, 0,0 )
qtr = mp.AngAxis(0,0,1,math.radians(i*30))
node.Rotation =MaxPlus.Quat(qtr)

結果はこうなります。Z回転をゼロから1回転繰り返しながらコピーしています。

前回の連載とあまり変わりません。forでの繰り返しを0~12で。先ほどのプログラムの応用で、新しいのは9行目だけです。

qtr = mp.AngAxis(0,0,1,math.radians(i*30))

qtrの値に軸はZ、角度をfor命令の「i」を30倍していますから、0度から360度になります。

この0,0,1を1,0,0にすれば、こうなります。

せっかくimport mathを使ったので、ちょっと応用してみましょう。

import randomというライブラリで乱数が使えます。

import MaxPlus as mp
import math
import random
obj = mp.Factory.CreateGeomObject(mp.ClassIds.Teapot)
obj.ParameterBlock.Radius.Value = 5.0
for i in range(13):
node = mp.Factory.CreateNode(obj)

x1 = random.uniform(1,100)
y1 = random.uniform(1,100)
Rz = random.uniform(0,360)

node.Position = mp.Point3(x1, y1,0 )
qtr = mp.AngAxis(0,0,1,math.radians(Rz))
node.Rotation =MaxPlus.Quat(qtr)

3行目にrandomを入れてます。これもPython標準の機能です。

9~11行目でrandom.uniformという命令が使えるようになります。後ろのカッコの2つ値がFloat(小数点以下あり)乱数の最大と最小値を設定します。

なのでx1,y1は1~100、Rzは0~360の乱数を作ります。

これをforで繰り返し行い、XYの位置とZ回転に代入しています。

実行結果はこうなります。

いかがですか?だいぶ3dsmaxのpythonが使えるようになってきましたね。