Google Android

November 14, 2007

Google have recently released their mobile phone software stack Android. I’ve had a quick look over some of the documentation, and so far I’m really impressed. It seems to give developers quite low level control over mobile devices, and supports loads of features:

  • Application framework enabling reuse and replacement of components
  • Dalvik virtual machine optimized for mobile devices
  • Integrated browser based on the open source WebKit engine
  • Optimized graphics powered by a custom 2D graphics library; 3D graphics based on the OpenGL ES 1.0 specification (hardware acceleration optional)
  • SQLite for structured data storage
  • Media support for common audio, video, and still image formats (MPEG4, H.264, MP3, AAC, AMR, JPG, PNG, GIF)
  • GSM Telephony (hardware dependent)
  • Bluetooth, EDGE, 3G, and WiFi (hardware dependent)
  • Camera, GPS, compass, and accelerometer (hardware dependent)
  • Rich development environment including a device emulator, tools for debugging, memory and performance profiling, and a plugin for the Eclipse IDE

What’s more, Google are offering $10 million in awards as part of the Android Developer Challenge! This YouTube video shows off some of the cool features:


Boids

November 12, 2007

Boids

I recently came across an article that mentioned boids, which is essentially a computer simulation of a flock a birds. Boids uses three simple rules, from which complex behaviour emerges. Having studied large scale distributed systems I’m familiar with emergent behaviour, but I haven’t seen anything that looks as impressive as boids.

The three rules of the Boid system are:

Rule 1: Don’t overcrowd near-by boids
Rule 2: Move closer to near-by boids
Rule 3: Move in the general direction of the other boids

I thought I’d have a crack at implementing my own boids. I hadn’t used PyGame before, but it looked ideal for this project.

First I came up with a basic boid class that stores the boids position and velocity.

class Boid:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.velocityX = random.randint(1, 10) / 10.0
        self.velocityY = random.randint(1, 10) / 10.0

I added a method to move the boid based on its velocity, and a method to detect the distance between two boids. Then I added the code for each of the rules.
Rule 1: Don’t overcrowd near-by boids.

    "Move away from a set of boids. This avoids crowding"
    def moveAway(self, boids, minDistance):
        if len(boids) < 1: return

        distanceX = 0
        distanceY = 0
        numClose = 0

        for boid in boids:
            distance = self.distance(boid)
            if  distance < minDistance:
                numClose += 1
                xdiff = (self.x - boid.x)
                ydiff = (self.y - boid.y) 

                if xdiff >= 0: xdiff = math.sqrt(minDistance) - xdiff
                elif xdiff < 0: xdiff = -math.sqrt(minDistance) - xdiff

                if ydiff >= 0: ydiff = math.sqrt(minDistance) - ydiff
                elif ydiff < 0: ydiff = -math.sqrt(minDistance) - ydiff

                distanceX += xdiff
                distanceY += ydiff 

        if numClose == 0:
            return

        self.velocityX -= distanceX / 5
        self.velocityY -= distanceY / 5

Rule 2: Move closer to near-by boids.

    "Move closer to a set of boids"
    def moveCloser(self, boids):
        if len(boids) < 1: return

        # calculate the average distances from the other boids
        avgX = 0
        avgY = 0
        for boid in boids:
            if boid.x == self.x and boid.y == self.y:
                continue

            avgX += (self.x - boid.x)
            avgY += (self.y - boid.y)

        avgX /= len(boids)
        avgY /= len(boids)

        # set our velocity towards the others
        distance = math.sqrt((avgX * avgX) + (avgY * avgY)) * -1.0

        self.velocityX -= (avgX / 100)
        self.velocityY -= (avgY / 100)

Rule 3: Move in the general direction of the other boids

    "Move with a set of boids"
    def moveWith(self, boids):
        if len(boids) < 1: return
        # calculate the average velocities of the other boids
        avgX = 0
        avgY = 0

        for boid in boids:
            avgX += boid.velocityX
            avgY += boid.velocityY

        avgX /= len(boids)
        avgY /= len(boids)

        # set our velocity towards the others
        self.velocityX += (avgX / 40)
        self.velocityY += (avgY / 40)

So that was the boid code sorted. Then all that was required was some code to tie it all together and display the boids:

pygame.init()

size = width, height = 800, 600
black = 0, 0, 0

maxVelocity = 10
numBoids = 50
boids = []

screen = pygame.display.set_mode(size)

ball = pygame.image.load("ball.png")
ballrect = ball.get_rect()

# create boids at random positions
for i in range(numBoids):
    boids.append(Boid(random.randint(0, width), random.randint(0, height)))   

while 1:
    for event in pygame.event.get():
        if event.type == pygame.QUIT: sys.exit()

    for boid in boids:
        closeBoids = []
        for otherBoid in boids:
            if otherBoid == boid: continue
            distance = boid.distance(otherBoid)
            if distance < 200:
                closeBoids.append(otherBoid)

        boid.moveCloser(closeBoids)
        boid.moveWith(closeBoids)
        boid.moveAway(closeBoids, 20)  

        # ensure they stay within the screen space
        # if we roubound we can lose some of our velocity
        border = 25
        if boid.x < border and boid.velocityX < 0:
            boid.velocityX = -boid.velocityX * random.random()
        if boid.x > width - border and boid.velocityX > 0:
            boid.velocityX = -boid.velocityX * random.random()
        if boid.y < border and boid.velocityY < 0:
            boid.velocityY = -boid.velocityY * random.random()
        if boid.y > height - border and boid.velocityY > 0:
            boid.velocityY = -boid.velocityY * random.random()

        boid.move()

    screen.fill(black)
    for boid in boids:
        boidRect = pygame.Rect(ballrect)
        boidRect.x = boid.x
        boidRect.y = boid.y
        screen.blit(ball, boidRect)
    pygame.display.flip()

I’m really impressed with the results! From the interaction of three simple rules some quite complex behaviour emerges.

Download the full Boid source code