Drawing Trees with PyCairo

I’ve been spending some time this evening playing around with PyCairo, which is a very handy drawing library for Python. Actually, Cairo is the underlying drawing engine and PyCairo is a set of Python bindings for it. Anyway, in this case, I’ve been playing with an idea I worked on during my PhD – generation of simple cartoon plants and other objects using various types of human input including vocalisations. This example is nothing so grand though – it’s just a really simple example of drawing a few random “trees” in an otherwise very uneventful landscape. Every time you run the example, you get different trees. A few example images are included below the code.

#
# trees.py - Generate an image of some random cartoon trees
# Written by Ted Burke
# Last modified 1-10-2012
#

import cairo
import random
import math

# Image dimensions
width, height = 640, 240

# Create a Cairo surface and context
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
ctx = cairo.Context(surface)

# Create gradient rectangle for the sky
pat = cairo.LinearGradient(0.0, 0.0, 0.0, 0.75 * height)
pat.add_color_stop_rgba(0, 1.0, 1.0, 1.0, 1)
pat.add_color_stop_rgba(1, 0.0, 0.0, 1.0, 1)
ctx.rectangle(0, 0, width, 0.75 * height)
ctx.set_source(pat)
ctx.fill()

# Create gradient rectangle for the ground
pat = cairo.LinearGradient(0.0, 0.75 * height, 0.0, 1.0 * height)
pat.add_color_stop_rgba(0, 0.0, 1.0, 0.0, 1)
pat.add_color_stop_rgba(1, 0.0, 0.5, 0.0, 1)
ctx.rectangle(0, 0.75 * height, width, 0.25 * height)
ctx.set_source(pat)
ctx.fill()

# Create a random number generator (0 <= value <= 1)
rnd = random.Random()

# Now generate a few random trees
for n in range(10):

	# Choose random values for bottom (b), top (t),
	# horizontal centre (x), trunk width (w), foliage radius (r)
	b = (0.75 + 0.25 * rnd.random()) * height
	t = b - ((0.25 + 0.5 * rnd.random()) * height)
	x = rnd.random() * width
	w = (0.025 + 0.025 * rnd.random()) * width
	r = w * (1.0 + 1.0 * rnd.random())

	# Draw trunk
	ctx.rectangle(x - w/2, b, w, t-b)
	ctx.set_source_rgb(0.2 + 0.4 * rnd.random(), 0.1 * rnd.random(), 0.0)
	ctx.fill()

	# Draw foliage
	ctx.arc(x, t, r, 0, 2 * math.pi)
	ctx.set_source_rgb(0.0, rnd.random(), 0.0)
	ctx.fill()

# Write out the image to a PNG file
surface.write_to_png("trees.png")

Here are some example images:

This entry was posted in Uncategorized and tagged , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s