#!BPY """ Name: 'Blender 3D Julia Fractals' Blender: 232 Group: 'Misc' """ ################################################################### # # # Blender Julia Set - version 0.0.0 # # # # v. 0.0.0 (C) March 2004 Stefano Selleri # # # # Released under the Blender Artistic Licence (BAL) # # See www.blender.org # # # ################################################################### # History # # V: 0.0.0 - 26-03-04 - The script starts to take shape, a # # history is now deserved :) # # 0.0.1 - 29-03-04 - Toggle to decide if inner vertices are to # # be created # ################################################################### import Blender from Blender import * from math import * VERSION = '0.0.0' Climit = Draw.Create(4.0) CN = Draw.Create(50) Ccx = Draw.Create(-0.2) Ccy = Draw.Create(0.8) Ccz = Draw.Create(0.0) Ccw = Draw.Create(0.0) Csectw = Draw.Create(0.2) Ccube = Draw.Create(1.0) Cdl = Draw.Create(0.1) RBmesh0 = Draw.Create(1) RBmesh1 = Draw.Create(0) bounds = [[1,0,0,0], [-1,0,0,0], [0,1,0,0], [0,-1,0,0], [0,0,1,0], [0,0,-1,0]] # see if time module is available try: import time timport = 1 except: timport = 0 #===========================# # Quaterninos manipulations # #===========================# # addition def qadd(q1, q2): return [q1[0] + q2[0], q1[1] + q2[1], q1[2] + q2[2], q1[3] + q2[3]] # multiplication def qmul(q1, q2): return [q1[0]*q2[0] - q1[1]*q2[1] - q1[2]*q2[2] - q1[3]*q2[3] , q1[0]*q2[1] + q1[1]*q2[0] + q1[2]*q2[3] - q1[3]*q2[2] , q1[0]*q2[2] + q1[2]*q2[0] + q1[3]*q2[1] - q1[1]*q2[3] , q1[0]*q2[3] + q1[3]*q2[0] + q1[1]*q2[2] - q1[2]*q2[1] ] # length def qabs(q): return sqrt(q[0]*q[0] + q[1]*q[1] + q[2]*q[2]+ q[3]*q[3]) #=====================# # Point in Julia Set? # #=====================# def injset(q,c,limit,N): flag = 0; i = 0; while (flag==0): q = qadd(qmul(q,q),c); if (qabs(q)>limit): flag=-1; i=i+1; if (i>N): flag=1; if (flag>0): r = 1; else: r = 0; return (r) #==================# # Create Verteices # #==================# def Julia(): global Climit,CN global Ccx,Ccy,Ccz,Ccw global Ccube,Csectw global RBmesh0,RBmesh1 global Cdl global bounds MeshNew = NMesh.GetRaw() xmax=Ccube.val ymax=Ccube.val zmax=Ccube.val dx=Cdl.val dy=Cdl.val dz=Cdl.val Mx = xmax/dx My = ymax/dy Mz = zmax/dz c = [Ccx.val, Ccy.val, Ccz.val, Ccw.val] limit = Climit.val N = CN.val w = Csectw.val for i in range(-Mx,Mx+1): print i, 'in [', -Mx, ',', Mx, ']' for j in range(-My,My+1): for k in range(-Mz,Mz+1): q = [i*dx,j*dy,k*dz,w] r = injset(q,c,limit,N) if r == 1: if RBmesh0.val==1: MeshNew.verts.append(NMesh.Vert(i*dx,j*dy,k*dz)) elif RBmesh1.val==1: inner = 1 n = 0 while (n < 6 and inner == 1): q = [(i+bounds[n][0])*dx,(j+bounds[n][1])*dy,(k+bounds[n][2])*dz,w] if(injset(q,c,limit,N)==0): inner=0 n = n + 1 if inner == 0: MeshNew.verts.append(NMesh.Vert(i*dx,j*dy,k*dz)) ObNew = NMesh.PutRaw(MeshNew) ############################################################# # Graphics # ############################################################# def Warn(): BGL.glRasterPos2d(115, 23) Blender.Window.Redraw(Blender.Window.Const.TEXT) def draw(): global Ccube,Climit,CN global Ccx,Ccy,Ccz,Ccw global Csectw,Cdl global RBmesh0,RBmesh1 global VERSION BGL.glClearColor(0.5, 0.5, 0.5, 0.0) BGL.glClear(BGL.GL_COLOR_BUFFER_BIT) BGL.glColor3f(0, 0, 0) # Black BGL.glRectf(2, 2, 482, 220) BGL.glColor3f(0.48, 0.4, 0.57) # Light Purple BGL.glRectf(4, 179, 480, 210) BGL.glRectf(4, 34, 480, 150) BGL.glColor3f(0.3, 0.27, 0.35) # Dark purple BGL.glRectf(4, 151,480, 178) BGL.glRectf(4, 4, 480, 33) RBmesh0 = Draw.Toggle("Full Set", 10,10,157,75,18,RBmesh0.val, "The full Julia set is created, as a cloud of vertices."); RBmesh1 = Draw.Toggle("No Inner", 11,90,157,75,18,RBmesh1.val, "The cloud of vertices contains only vertices next to the boundary."); Ccx = Draw.Slider("c.x:", 2, 10, 100, 230, 18, Ccx.val, -1., 1., 1, "Offset parameter c, 1st co-ordinate") Ccy = Draw.Slider("c.y:", 2, 10, 80, 230, 18, Ccy.val, -1., 1., 1, "Offset parameter c, 2nd co-ordinate") Ccz = Draw.Slider("c.z:", 2, 10, 60, 230, 18, Ccz.val, -1., 1., 1, "Offset parameter c, 3rd co-ordinate") Ccw = Draw.Slider("c.w:", 2, 10, 40, 230, 18, Ccw.val, -1., 1., 1, "Offset parameter c, 4th co-ordinate") Ccube = Draw.Slider("cube:", 2, 245, 120, 230, 18, Ccube.val, 0.1, 4.0, 1, "Half side of the cube where fractal is sought for") Climit = Draw.Slider("boundary:", 2, 245, 100, 230, 18, Climit.val, 1., 100., 1, "Boundary beyond which the quaternion is considered divergent") CN = Draw.Slider("Iterations:", 2, 245, 80, 230, 18, CN.val, 2, 1000, 1, "Maximum number of iteration per point") Cdl = Draw.Slider("Step:", 2, 245, 60, 230, 18, Cdl.val, 0.001, 0.5, 1, "refinement of the search") Csectw = Draw.Slider("Hyperplane w:", 2, 245, 40, 230, 18, Csectw.val, -1., 1., 1, "4th coordinate of the hyperplane slicing the Julia Set") BGL.glColor3f(1, 1, 1) BGL.glRasterPos2d(8, 200) Draw.Text("Blender Julia Set - V. 0.0.0 - 26 March 2004") BGL.glRasterPos2d(8, 185) Draw.Text("by Stefano Selleri") Draw.Button("Exit", 1, 430, 185, 40, 20) #Create Buttons Draw.Button("CREATE", 4, 10, 10, 465, 18, "Create a cloud of vertices in the Julia Set") def event(evt, val): if evt == Draw.QKEY and not val: Draw.Exit() if evt == Draw.CKEY and not val: Julia() Draw.Redraw() def bevent(evt): global RBmesh0,RBmesh1 if evt == 1: Draw.Exit() elif evt == 4: Julia() Draw.Redraw() elif evt == 10: RBmesh0.val = 1 RBmesh1.val = 0 Draw.Redraw() elif evt == 11: RBmesh0.val = 0 RBmesh1.val = 1 Draw.Redraw() Draw.Register(draw, event, bevent)