Ziye Liu's Blog
  • ( www.ziyeliu.com )
  • Home
  • Visual Effects Blog
    • Houdini >
      • Procedural Courtyard House
      • Procedural Music Animation
    • Maya - MEL >
      • MEL Rooftop Generator
      • MEL Circle of Spheres
    • Maya - Rendering >
      • Maya Render Premultiply Issue
      • Depth of Field and Bokeh
      • 3D Render - Match to a Real Object
      • RenderMan I
      • RenderMan II
    • Python >
      • Python Sampler Quilt
      • Motion Capture Data Parsing
      • Python and Turtle Graphics
  • Themes & Variations
    • The Film
    • Scene 1 - "Crazy Polka Dots"
    • Scene 2 - “Untitled”
    • Scene 3 - "Grapes"
    • Scene 4 - “Narcissus Garden”
  • 中文博客

Python Turtle Graphic

A Sampler Quilt

By Ziye Liu
M.F.A. Visual Effects, 2012
April 4th, 2013
Introduction
To generate 2D geometric patterns using programming language, is an easy way to get familiar with some of the fundamental programming concepts. 
By breaking down elements in those commonly seen quilt patterns then design algorithms to reproduce them automatically , a computer program is build with functions such as customizable quilt size, dimensions and color scheme. 
This is the first assignment of Prof. Deborah R. Fowler's VSFX 705 - Programming Concept class in Spring 2013.
Picture
Version 1
5 Patterns, 6 Color Sets in a 5 by 5 Sampler Quilt
March 31st, 2013
Picture
Version 2
Allow user to control the number of rows and columns by typing a number (in the picture above, the number is 3). 
Also able to control the sampler quilt's size in pixel unit.
Rewrite "Winding Way" pattern's algorithm, add repeating function.
April 4th, 2013

Download

Picture
The finished code.
Sampler Quilt v2.py

The assignment's purpose is to get familiar with basic programming concepts such as Variable, If Statement, Loop and Function. By making a sampler quilt using Python's Turtle Graphic Library, more concepts such as Algorithm, Modulus and Nested Loops are introduced.
By the time when dealing with this exercise, I do not have programming background, and my mathematic knowledge is very limited. 

The Sampler Quilt

Finished Images

Algorithm

I planned on having 5 different design of quilt blocks, and let the program choose the color palette from 6 different color sets.
In order to let the quilt blocks appear in a cyclic movement, I designed 3 different solutions:
  • Using If Statement - but it turns out to be inefficient.
  • Using List, then update it on each row - not working as expected.
  • Using Loop, then use Modulus - works perfectly.
Picture
The goal is to let the user type in a series of number, such as QuiltRows and QuiltColumns, then the program will decide how to arrange these patterns and draw them in an appropriate position.
Picture
In order to have a more appealing visual of the whole image, each quilt block has a gap area in between. There's also an outside frame for the finished quilt, and it scales proportionally with the quilt's dimension.
Picture
Some note for designing the cyclic algorithm

What is a Sampler Quilt?

It's a quilt with each block has a different pattern, such as these...
Picture
Most of the pattern distribution rule in these sampler quilts are designed by the quilt maker. However, the requirement here is to draw these patterns in a cyclic manner.

The Quilt Patterns

The following examples are about the five patterns included in the final sampler quilt, each of them has unique figure and geometric shape. 
For each pattern there is a new challenge, such as pattern repetition, dashed line, triangular shape, etc. 

The First Pattern - "Winding Ways"

or, "Wheel of Mystery"
For the first sampler quilt pattern, I choose a traditional American quilt pattern called "Winding Ways", also known as "Wheel of Mystery".
The pattern is famous for its repetition of illusionary circular shapes. That makes it quite a funny one to begin with.
March 30th, 2013
Picture
"Winding Ways", finished pattern in a single block.

Algorithm for this pattern

Algorithm for drawing the Arc Shape
  1. ...
  2. Step 1. Draw a single arc shape. Rotate 90°. Repeat this step for 4 times. Fill it with Color A.
  3. Step 2. Move on to next sub-block position.
  4. Step 3. Repeat Step 1 and 2, until 4 sub-blocks are finished. UPDATED APR-4th: Repeat Step 1 and 2 in a loop, which move the turtle position based on the row and column number.
  5. ...
Algorithm for assigning color
  • If the color in Last Step is A, then fill it with Color B; if not, keep it with A.
  • UPDATED APR-3rd: New Algorithm: fill color using modulus, depends on row number and column number.
Traditionally this pattern will be repeated several times to form a large circle appeared on the quilt, so the pattern and its color attribute  must be repeatable, regardless of its size and position.
Picture
"Winding Ways", finished pattern in a repetition quilt, with the illusionary circles.

Difficulties

  • Drawing arc lines.
  • Fill the arc shape with color.
  • Angle, orientation and alignment of each shape and block.
  • Repeat the small block (before it was 4 times) as many times as expected with the color switching.

Solution

  • Use the turtle.circle() command to draw the arc shape by segments.
  • Set up a variable for the color choice, then use the turtle.begin_fill(), turtle.fillcolor() and turtle.end_fill() commands to set the filling color to color choice.
  • Using Loop to draw the pattern 4 times, and update the color variable in each loop.
  • Nested Loops, update color choices and pattern position in each loop.
"Winding Ways", screen-recorded animation
Picture
Reference from "Patchwork Quilt Text Book" published by ...
Full Code Download:
winding_ways_pattern.py
File Size: 4 kb
File Type: py
Download File

winding_ways_pattern_v2.py
File Size: 1 kb
File Type: py
Download File

##    New Version Algorithm, can control the repetition number
##    and assign color using modulus
    currentColorList = [color1, color2]
    for j in range(0,arcRepeat):
        moveit(currentPos)
        y = turtle.ycor()
        for i in range(0,arcRepeat):
            x = turtle.xcor()
            turtle.pu()
            turtle.goto(x + i * glbBlockLength/arcRepeat, y - j * glbBlockLength/arcRepeat)
            turtle.pd()
            turtle.seth(0)
            drawSubBlock(currentColorList[0 + (i+j+1) % 2])
            gotoSubBlockCenter()
            drawArcBlock(currentColorList[0 + (i+j) % 2])
            moveit(currentPos)
        turtle.seth(0)
    def drawArcPiece(color):
        turtle.begin_fill ()
        turtle.fillcolor(color)
        turtle.circle(glbBlockLength/2, 360/12)
        turtle.right(360/6)
        turtle.circle(glbBlockLength/2, -(360/12))
        turtle.right(360/6)
        turtle.circle(glbBlockLength/2, 360/12)
        turtle.end_fill ()
  
    def drawArcBlock(color):
        for i in range(0,2):
            drawArcPiece(color)
            turtle.right(90)
            drawArcPiece(color)
        gotoBlockCenter(-1,4)

The Second Pattern - "Blazing Star"

Picture

Algorithm for this pattern

  • ...
  • Draw a single Diamond Shape to be the basic element.
  • Reset Turtle's position.
  • Turn right 45°, thus it will draw in clockwise.
  • Draw another Diamond Shape.
  • Repeat steps above until finished half of the first layer.
  • Mirror the Diamond Shape, then draw in -45° (or left 45°, counterclockwise) direction. Finished the other half.
  • First layer is done.
  • ...

Difficulties

  • Have to draw the diamond shapes by layer order, so that can fill them with the correct color palette.
  • Set Turtle's position to prepare for drawing the next element, then the next layer.
  • Drawing the last 8 diamond shapes, which are difficult to locate.
    #3rd layer middle
    ## use this offset function to draw the diamond shape into it's position
    def offsetMid(a,b):
        turtle.penup()
        turtle.forward(diamondSide*a)
        turtle.right(45)
        turtle.forward(diamondSide*b)
        turtle.left(45)
        turtle.pendown()
    for i in range(0,8):
        cCenterPos = turtle.pos()
        offsetMid(-1,1)
        turtle.begin_fill()
        turtle.fillcolor(color4)
        drawDiamond(diamondSide, 2, 1)
        turtle.end_fill()
        turtle.penup()
        turtle.goto(cCenterPos)
        turtle.pendown()
        turtle.right(45)

Solution

  • Rotate in positive degree will draw the diamond shapes clockwise, then rotate Turtle in negative degree will draw them counterclockwise. This will finish a single layer.
  • Draw the pattern layer by layer. From the center to the second then third layer. Finally draw the remained 8 diamond shapes.
  • By offset Turtle's beginning position to fit with one of the last 8 diamond shape's position, draw a normal diamond shape, then reset Turtle's position.
Picture
"Blazing Star", screen-recorded animation
blazing_star.py
File Size: 2 kb
File Type: py
Download File

    #3rd layer clockwise
    for i in range(0,8):
        turtle.begin_fill()
        turtle.fillcolor(color4)
        drawDiamond(diamondSide, 2, 1)
        turtle.right(45)
        turtle.end_fill()
    #3rd layer counter clockwise
    for i in range(0,8):
        turtle.begin_fill()
        turtle.fillcolor(color4)
        drawDiamond(diamondSide, 2, -1)
        turtle.right(45)
        turtle.end_fill()

The Third Pattern - "Log Cabin"

Picture
Picture

Algorithm for this pattern

This pattern are in common with many programming concept, such as loop and nested loops.
In order to draw each rectangle shape with incremental length, while maintain the same width, a simple algorithm is used to define a function which will draw rectangles based on the layer order it's in.

Dashed Line

In addition to the basic pattern design, some details are added for a more appealing visual.
I developed an algorithm to draw the dashed lines within each rectangle shape. Thus it became the major challenge in this pattern.

Difficulties

  • Must be able to draw the dashed line as normal straight lines, in other words, to be customizable in steps and length.
  • Must have the ability to stop drawing dashed lines when approaching it's destination, and finish the rest of the dashed line in appropriate manner. This is critical to preserve the "corner" when drawing a dashed line rectangle.

Solution

  • Define a function with an argument specifying the full length of the expected dashed line.
  • During each loop, using an IF statement which modulus to test if the current loop number is odd or even. 
  • If the current loop number is odd, then draw as normal straight lines. If it's an even number, then draw nothing but proceed.
  • Before reaching the destination point, calculate if the rest of the dashed line exceed the length of a single step.
  • If the remain length exceeds the length of a single step, then draw a single step, then proceed to the destination with turtle's pen down.
  • If the remain length does not exceeds the length of a single step, then proceed directly to the destination with turtle's pen down.
Also, defined more functions doing the job of setting up beginning position, and make sure the turtle returns to it's beginning position after successfully drawing a dashed line rectangle.
dashed_line_function.py
File Size: 0 kb
File Type: py
Download File

log_cabin.py
File Size: 2 kb
File Type: py
Download File

## Dashed Line Function
def dashline (length, dashLength):
    beginPos = turtle.pos()
    
    ##the remain length of the whole dash line:
    remainlength = length
    
    ##set the step number needs to draw the dash line:
    for dashStep in range (0, (length - length % dashLength)/dashLength/2+1):
##        print "Dash Step:", dashStep
        
        ##draw the dash line
        if remainlength >= dashLength * 2:
            turtle.pendown()
            turtle.forward(dashLength)
            turtle.penup()
            turtle.forward(dashLength)
            ##update the remainlength
            remainlength = remainlength - dashLength * 2
  
        ##draw the last step, based on the remain length        
        elif remainlength < dashLength *2:
            turtle.pendown()
            turtle.forward(remainlength)

The Fourth Pattern - "Marinerd's Compass"

Picture
Picture
Picture

Algorithm for this pattern

The major challenge here is to draw each triangle shape in certain order, so that they could form a compass with layers.

Difficulties

  • Had to calculate the triangle value.
  • Maintain 4 triangles as one group, then repeat the group in order.
  • Align each triangle as well as each group.

Solution

Keep in mind that the sin and cos function's input value is in radiance by default.
Picture
Reference from "Patchwork Quilt Text Book".

The Fifth Pattern - "Storm at Sea"

Picture
Picture

Resources and External Link

Python Programming
Instructions and information on Professor Deborah R. Fowler's website.
Useful documentation about Python Programming and Turtle Graphic.
The Python Code embed as HTML in this webpage is converted using Professor Malcolm Kesson's Cutter Text Editor. Also there's some useful information about Python programming on his website.
Quilt Pattern
Reference Books
  • 5,500 Quilt Block Designs by Maggie Malone, ISBN-13: 978-1-4027-2047-5, Sterling Publishing Co., Inc. New York.
  • Patchwork Quilt Text Book (Japanese) by Japan Handicraft Instructors' Association (パッチワークキルト,公益財団法人日本手芸普及協会)
Online Resources
  • Antique Geometric by earlywomenmasters.net
Adobe® Kuler®.
Picture
5,500 Quilt Block Designs by Maggie Malone ISBN-13: 978-1-4027-2047-5 Sterling Publishing Co., Inc. New York.
Picture
Patchwork Quilt Text Book by Japan Handicraft Instructors' Association
www.ziyeliu.com
Digital Art, Visual Effects, Photography
©Ziye Liu, 2011 - 2019, All Rights Reserved