コッホ曲線でオーロラ(その2)

グラデーションをつけた

パラメータをいじりながら色々試してみる。横方向はHaloの間隔が離れていてもむしろ「のっぺりしていない」感じが出るが、縦方向は間隔があいていると謎のつぶつぶになってしまう。あと、アルファ値は小さめにした方が重なったときに飽和しないからきれいだな。

ソースコードはサンプルコードを切り貼りしながら試行錯誤してつくったので汚い。

from Blender.Mathutils import Vector
from Blender import *
from math import sin, cos, pi

class Turtle(object):
    def __init__(self):
        self.x = 0.0
        self.y = 0.0
        self.dirx = 1.0
        self.diry = 0.0
        self.vert2d_list = [(0.0, 0.0)]
        self.faces = []

    def forward(self, mag):
        self.x += self.dirx * mag 
        self.y += self.diry * mag 
        self.vert2d_list.append((self.x, self.y))

    def rot(self, rad):
        self.dirx, self.diry = (
            self.dirx * cos(rad) - self.diry * sin(rad),
            self.dirx * sin(rad) + self.diry * cos(rad))
    
    def build_mesh(self, z=0.0, name="Mesh"):
        verts3d = [Vector(x, y, z) for (x, y) in self.vert2d_list]
        me = Mesh.New(name + str(z))          # create a new mesh
        me.verts.extend(verts3d)          # add vertices to mesh
        me.faces.extend(self.faces)           # add faces to the mesh (also adds edges)
        return me

def deg(x):
    return 2 * pi / 360 * x

def makeHalo(x):
    mat = Material.New('Halo')          # create a new Material called 'newMat'
    mat.rgbCol = [0.7 * x, 0.7, 0.1]          # change its color
    mat.setAlpha(0.3 * (1 - x))                     # mat.alpha = 0.2 -- almost transparent
    #mat.emit = 0.7                        # equivalent to mat.setEmit(0.8)
    #mat.mode |= Material.Modes.ZTRANSP    # turn on Z-Buffer transparency
    #mat.setAdd(0.8)                       # make it glow
    mat.setMode('Halo')                   # turn 'Halo' "on" and all others "off"
    return mat

def koch(level=1, unit=1):
    if level == 0:
        turtle.forward(unit)
    else:
        koch(level - 1, unit)
        turtle.rot(deg(60))
        koch(level - 1, unit)
        turtle.rot(deg(-120))
        koch(level - 1, unit)
        turtle.rot(deg(60))
        koch(level - 1, unit)
        

turtle = Turtle()
koch(4, 0.6)

for i in range(100):
    ob = Object.New('Mesh', 'myObj')  # link mesh to an object
    m = turtle.build_mesh(i / 5.0)
    m.materials += [makeHalo(i / 100.0)]
    ob.link(m)

    sc = Scene.GetCurrent()          # link object to current scene
    sc.link(ob)