Python 2.6 Graphics Cookbook
上QQ阅读APP看书,第一时间看更新

Drawing intricate shapes – the curly vine

The task here is to draw a complicated shape in such a way that you can use it as a framework to produce unlimited variety and beauty.

We start out with a pencil and paper and draw a curly growing vine shape and transfer it in the simplest and most direct way into some code that will draw it.

This is a very important example because it reveals the essential elegance of both Python and Tkinter. The central inspiring design philosophy of Python is captured in two words: simplicity and clarity. This is what makes Python one of the best computer coding languages ever conceived.

Getting ready

When they want to create a fresh design, most graphic artists start with a pencil and paper sketch because of the uncluttered subconscious freedom it gives. For this example, a complex curve was needed – the kind of organic design used in framing pictures in antique books.

The smooth line was drawn with a pencil on paper and marked off at roughly, evenly spaced intervals with X's. Using a millimeter marked ruler the distance from each x to the left edge and the bottom of the paper was measured approximately. High accuracy is not needed because the curved nature of the line compensates for small imperfections.

How to do it…

These measurements, 32 each in the x and y directions for a Tkinter canvas were typed into separate lists. One called x_vine for the x coordinates and y_vine for the y coordinates.

Besides this hand-crafted way of creating the raw shape, the rest of the procedure is identical for all the previous examples.

# vine_1.py
#>>>>>>>>>>>>>
from Tkinter import *
root = Tk()
root.title('Curley vine ')
cw = 180                                      # canvas width.
ch = 160                                      # canvas height.
canvas_1 = Canvas(root, width=cw, height=ch, background="white")
canvas_1.grid(row=0, column=1)

# The curly vine coordinates as measured from a paper sketch.
vine_x = [23, 20,  11,  9, 29, 52, 56, 39, 24, 32, 53,  69,  63,  47,  35,  35, 51,\
  82, 116, 130, 95, 67, 95, 114, 95, 78, 95, 103, 95, 85, 95, 94.5]

vine_y = [36, 44, 39, 22, 16, 32, 56, 72, 91, 117,125, 138, 150, 151, 140, 123, 107,\
 92,  70,  41,  5, 41, 66,  41, 24, 41, 53,  41, 33, 41, 41, 39]
#=======================================
# The merging of the separate x and y lists into a single sequence.
#=======================================
Q =  [ ]
# Reference copies of the original vine lists - keep the originals # intact
X = vine_x[0:]
Y = vine_y[0:]

# Name the compact, merged x & y list Q
# Merge (alternate interleaves of x and y) into a single polygon of # points.
for i in range(0,len(X)):
    Q.append(X[i])    # append the x coordinate
    Q.append(Y[i])    # then the y - so they alternate and you end # with a Tkinter polygon.
canvas_1.create_line(Q, smooth='true')
root.mainloop()
#>>>>>>>>>>>>

How it works...

The result is shown in the next screenshot which is a smoothed line of 32 straight segments.

How it works...

The essential trick in this task is to create a list of numbers that is in precisely the correct form to place into a create_line() method. It has to be an unbroken sequence, comma-separated, of pairs of matched x and y position coordinates of the complex curve we want to draw.

So first we create an empty list Q[] to which we are going to append alternate values of the x and y coordinates.

Because we want to leave the original lists x_vine and y_vine intact (for re-use elsewhere perhaps) we create working copies using:

 X = vine_x[0:]
 Y = vine_y[0:]

And finally the magic interleaved merging into one list with:

 for i in range(0,len(X)):
    Q.append(X[i])    # append the x coordinate
    Q.append(Y[i])    # then the y

The for in range() combination and the block of code following it work cyclically through the code starting at i=0, increasing one by one each until the last value len(X) is reached. Then the block of code is exited and execution continues below the block. Len(X) is a function that gives back ('returns' in programmers' parlance) the number of elements in X. Q emerges from this perfect for immediate drawing in create_line(Q).

If you leave out the smooth='true' attribute you will see the original join points that came from the original paper draw and measure process.

There's more...

Some interesting effects like curling smoke, charcoal, and glowing neon are produced by copying and transforming the curly vine in various ways in Chapter 6, Working with Pictures.