Fall2006.Boids History

Hide minor edits - Show changes to output

Added lines 1-148:
(:source lang=Python tabwidth=3 -trim :)

# boid.py Version 1.0 9-oct-06 (bzm)
# Models a spherical boid, in terms of its position, velocity,
# and color in VPython.

from visual import *
from math import *
from random import *

# screen setup
universe = display(title='Boids')
universe.fullscreen = True
universe.autoscale = False
rate(24) # max allowable iterations per second

class Boid(sphere):
"Models a spherical boid, in terms of its position, velocity, radius, and color."

def __init__(self, pos=vector(0,0,0), velocity=vector(0,0,0), radius=0.2, color=color.blue):
"Construct a boid."
sphere.__init__(self, pos=pos, radius=radius, color=color)
# self.pos # inherited attribute used to store boid position

def setVelocity(self, velocity):
"Set boid's velocity."
self.velocity = velocity

def getVelocity(self):
"Returns boid's velocity."
return self.velocity

def setPos(self, pos):
"Set boid's position."
self.pos = pos

def getPos(self):
"Get boid's position."
return self.pos

def move(self, timePassed):
"Move boid to new position based on its velocity and time passed."
self.pos = self.pos + self.velocity * timePassed

def distance(self, other):
"Returns our (3D Euclidean) distance from the other boid."
return sqrt((self.pos.x - other.pos.x)**2 +
(self.pos.y - other.pos.y)**2 +
(self.pos.z - other.pos.z)**2)

def randomBoids(boids, numBoids, radius, color):
"Returns a list of 'numBoids' boids with random position and velocity."

# initialize boids
for i in range(0, numBoids):
randPos = randomVector(-1, 2) # get a random vector
randVelocity = randomVector(-1, 2) # get a random vector
# create a boid with random position
boids.append( Boid(pos=randPos, velocity=randVelocity, radius=radius, color=color) )
return boids

def randomVector(low, high):
"Returns a vector with random components, each ranging between low and high-1."
x = randrange(low, high)
y = randrange(low, high)
z = randrange(low, high)
return vector(x,y,z)

def placeBoidsViaMouse(boids, numBoids, radius, color):
"Returns a list of 'numBoids' boids with position and velocity entered via mouse clicks."

# initialize boids
boidsCreated = 0
# wait for mouse clicks
while boidsCreated < numBoids:
if universe.mouse.clicked: # if mouse was clicked
mouseClick = universe.mouse.getclick()
pos = mouseClick.pos # get its coordinates
# create a boid with specified position
boids.append( Boid(pos=pos, radius=radius, color=color) )
boidsCreated = boidsCreated + 1 # update
return boids

def moveBoidViaMouse(boids):
"Allows boid repositioning via mouse drag-n-drop."
# see http://www.vpython.org/webdoc/visual/mouse_drag.html

boidPicked = None # no boid picked out of the scene yet

# is there some mouse activity?
if universe.mouse.events:

event = universe.mouse.getevent() # yes, so obtain mouse event
# if clicked on a boid
if event.drag and event.pick in boids:

boidPicked = event.pick # remember which boid was picked
drag_pos = event.pickpos # where on the boid the mouse was
universe.cursor.visible = 0 # make cursor invisible

elif event.drop: # released mouse button at end of drag
boidPicked = None # release boid
universe.cursor.visible = 1 # cursor visible again

if boidPicked: # is there a boid to reposition?
#new_pos = universe.mouse.project(normal=(0,1,0)) # project onto xz plane
new_pos = universe.mouse.pos # get mouse position
if new_pos != drag_pos: # if the mouse has moved since last time
offset = (new_pos - drag_pos) + boidPicked.getPos()
boidPicked.setPos(offset) # update boid position using offset
drag_pos = new_pos # remember where we drag this boid

def test():
"Place a few boids randomly on the screen and move the around."

boids = [] # list of boids
numBoids = input("Enter number of boids: ")

#boids = randomBoids(boids, numBoids, radius=0.2, color=color.yellow)
boids = placeBoidsViaMouse(boids, numBoids, radius=0.2, color=color.yellow)

# animate boids (press 'Escape' to end)
while (True):

# move them around a bit
for boid in boids:
boid.move(0.005) # adjust boid position
print "another cycle..."

# check mouse events and update boids as specified

#wait = input("Paused (press a key and Enter to continue)")


if __name__ == '__main__':