2016年8月5日金曜日

BlenderをPythonで動かして重力波を描く

重力波を描きたい、と思いたち、どうにかBlenderでそれっぽいのを作れたのでメモ。

これが完成版。



参考にしたサイト



プログラム(Python)

import bpy
import numpy as np

# 一旦すべてのオブジェクトを消す
for item in bpy.context.scene.objects:
    if item.type == 'MESH':
        bpy.context.scene.objects.unlink(item)
for item in bpy.data.objects:
    if item.type == 'MESH':
        bpy.data.objects.remove(item)
for item in bpy.data.meshes:
    bpy.data.meshes.remove(item)
for item in bpy.data.materials:
    bpy.data.materials.remove(item)

theta = 0

# mesh arrays
verts = []
faces = []

# mesh variables
numX = 200
numY = 200

# wave variables ここは好きに変更してください
amp = 15 # 振幅
lam = 3 # 波長
scale = .15 # 数値が小さければ細かいグリッドになる

#fill verts array
for i in range (-numX, numX):
    for j in range(-numY, numY):

        x = scale * i
        y = scale * j
        R1 = amp * np.cos(2 * np.arctan(y/(x + 0.00001)) - theta + lam * np.sqrt(x**2 + y**2))
            # 2は中心から出る波形の数
        R2 = 60 + np.sqrt(x**2 + y**2)
        z = R1/R2

        vert = (x,y,z)
        verts.append(vert)

#fill faces array
count = 0
for i in range (0, 2*numY * (2*numX-1) ):
  if count < 2*numY-1:
      A = i # 1番目の点
      B = i+1 # 2番目の点
      C = (i+2*numY)+1 # 3番目の点
      D = (i+2*numY) # 4番目の点

      face = (A,B,C,D)
      faces.append(face)
      count = count + 1
  else:
      count = 0

#create mesh and object
mesh = bpy.data.meshes.new("wave")
object = bpy.data.objects.new("wave",mesh)

#set mesh location
object.location = bpy.context.scene.cursor_location
bpy.context.scene.objects.link(object)

#create mesh from python data
mesh.from_pydata(verts,[],faces)
mesh.update(calc_edges=True)