Blender 2.8で3DのSurfacePlotをする

Blender

Blenderで数式に基づいたオブジェクトを生成したいと思って, スクリプトを書きました.
スクリプトの結果はSurfacePlotのようになります.

次のblender-wave.pyをBlender v2.8で実行すると上の画像のオブジェクトが作成されます.


import bpy
import numpy as np
import math
import mathutils
def WaveXY(x, y, x0=0, y0=0, period=1, a=1):
# Cos Wave
r = np.sqrt((x x0) ** 2 + (y y0) ** 2)
return a * np.cos(2.0 * np.pi * r / period)
# 初期化
cols = 101
rows = 101
mat = np.zeros((rows, cols))
x_array = np.linspace(0, 10, num=cols)
y_array = np.linspace(0, 10, num=rows)
verts = []
# Update Matrix
for y in range(0, rows):
for x in range(0, cols):
px = x_array[x]
py = y_array[y]
# 水面波の干渉
t = 2.5
mat[y, x] += WaveXY(px, py, x0=0, y0=0, period=t)
mat[y, x] += WaveXY(px, py, x0=10, y0=10, period=t)
verts.append(mathutils.Vector([px, py, mat[y, x]]))
fIndexes = [] # 面のリスト
for y in range(0, rows 1):
for x in range(0, cols 1):
fIndexes.append([x + y * rows,
x + 1 + y * rows,
x + 1 + (y + 1) * rows,
x + (y + 1) * rows])
mesh = bpy.data.meshes.new('wave')
mesh.from_pydata(verts, [], fIndexes) # 点と面の情報からメッシュを生成
obj = bpy.data.objects.new('wave', mesh) # メッシュ情報を新規オブジェクトに渡す
bpy.context.scene.collection.objects.link(obj) # オブジェクトをシーン上にリンク(v2.8)
# bpy.context.scene.objects.link(obj) #v2.7
obj.select = True# 作ったオブジェクトを選択状態に
view raw

blender-wave.py

hosted with ❤ by GitHub

スクリプトの実行は画像のようにScriptingレイアウトで行うのがお勧めです.

ではここからコードの解説をしていきます.

  • 1–4行目
    必要なパッケージをインポートしています. もし, numpyが入っていなかったらインストールしてください.

  • 7–10行目
    正弦波を書くためのWaveXYという関数を定義しています. この関数は点(x,y)における波の高さ(z座標)を返します. (x0,y0)は波の中心, periodは波の周期, aは波の振幅です.

  • 13–18行目
    プロットに必要な変数を設定しています. 肝は行列のmatです. この行列のサイズは’rows x cols’です. この後, このmatに波のz座標を代入していきます. x_arrayy_arrayはそれぞれx軸とy軸用の配列です. 今回は両方とも0–10の範囲で宣言しました. vertsはこの後, 頂点の位置ベクトルを格納するための配列です. なお, 行列のサイズを大きくすればより精度の高いプロットを行うことができます.

  • 21–29行目
    行列matに波の高さを代入し, vertsに点の位置ベクトルを追加しています. mat[y,x]に点(px,py)の波の高さを代入しています. ちなみに今回プロットしているのは正弦波の干渉縞です.

  • 31–38行目
    面のリストfindexesに面を生成する点の座標を追加しています. Blenderではvertsのインデックスを指定することで面を貼ります. 今回は, 左上, 右上, 右下, 左下の順に点のインデックスを指定して四角形メッシュを貼っています.

  • 41–47行目
    vertsfindexesを使ってメッシュを持ったオブジェクトを作成し, シーンに追加しています. Blender v2.8以降とv2.7以前ではオブジェクトのシーンへの追加方法が異なるので注意してください. dskjalさんがその辺りを解説してくれているので, 気になる方はご参照ください.

Blender 2.79 のスクリプトを 2.80 にアップデートする

今回のスクリプトの29行目のz座標を変更するだけでも, 様々な関数をプロットすることができます. ガウシアンポン・デ・リングも描けるはずなので挑戦してみてください.

コメント

タイトルとURLをコピーしました