from visual import * from random import * from time import * ################### Function definitions ## Detects collisions betweens a list of spheres of radius 1 ## and a single sphere of radius 1. If no overlap, returns 1. ## If there is an overlap, returns 0. def nocollision(spherelist, currsphere): for s in spherelist: if mag(s.pos-currsphere.pos) <= 2: return 0 return 1 ## Pick a random direction vector def randomdirection(): d = vector(1,1,1) while mag(d) > 1: d = 2.0 * vector(random()-0.5,random()-0.5,random()-0.5) return d / mag(d) ################### Program start scene.autoscale = 0 scene.background = (0.8,0.8,0.8) print "Diffusion limited aggregation simulation." print "The printed output is the mass of the aggregate and radius of sphere" print "centered at original sphere that contains the aggregate." print "(Each sphere has mass 1, so mass is just number of spheres.)" print "" massgoal = input("Put how many spheres in the aggregate?") ## Initialize the aggregate aggregate = [sphere(color=color.blue)] ## initial sphere is blue aggregateradius = 1.0 while len(aggregate) < massgoal: ## start a particle at the edge of sphere around aggregate s = sphere(color=color.green, pos=(aggregateradius+1.)*randomdirection()) ## Move particle randomly until it collides with aggregate (sticks). while nocollision(aggregate,s): s.pos += randomdirection() if mag(s.pos) > 2. * aggregateradius: ## too far - reset s.pos = (aggregateradius+1.)*randomdirection() ## Now have collision! aggregate.append(s) s.color = color.red ## Update size of aggregate, if new particle extends radius if (mag(s.pos)+1) > aggregateradius: aggregateradius = mag(s.pos) + 1 print "#", len(aggregate), "stuck; aggregate radius is", aggregateradius print "" print "Run finished with radius of", aggregateradius