15-110 Spring 2013 [Kaynar/Gunawardena]

Lab 6 - Thursday, February 21, 2013

Deliverables

  1. canvas.rb
  2. triangle.rb
  3. carpet.rb
  4. my_fractal.rb

Place these files in a lab6 folder. Before leaving lab, zip up the lab6 folder and hand the zip file in.

RubyLabs Canvas Information

This lab uses the Canvas facility for graphics provided by RubyLabs. If you were not present for Lab 4 (with the time operation), you will need to setup RubyLabs before beginning this lab.

CA-Led Activities/Demonstration

Self-Directed Activities

  1. Consider the figure shown at right. This can be drawn using the RubyLabs Canvas operations:

    Canvas.init(width,height,name)
    Canvas::Rectangle.new(x0,y0,x1,y1)
    Canvas::Circle.new(x0,y0,radius)
    
    Here is an example using these methods that you can try:
    Canvas.init(100,300,"MyStuff")
    Canvas::Rectantle.new(75,150,85,250)
    Canvas::Circle.new(60,190,15)
    

    In the file canvas.rb create a function draw_image() that initializes a canvas 202 pixels by 202 pixels and draws the figure shown at right.


  2. The image to the right is a Sierpinski's Triangle (albeit, rotated and with a different angle than the canonical form). It is a fractal; that is, it is "a rough or fragmented geometric shape that can be split into parts, each of which is (at least approximately) a reduced-size copy of the whole." In this case, you will notice that, if you look at the lower-right corner, it looks the same (down to the level of one pixel) at different levels of magnification.

    Starting with a completely filled-in square, this Sierpinski's Triangle can be produced with the following procedure:

    1. Return nil if the image is too small to be visibly subdivided.
    2. Otherwise, consider the square being divided up into four quadrants (squares).
    3. Draw a square (rectangle with equal sides) in the upper-left quadrant.
    4. Recursively draw a Sierpinski triangle in each of the other three quadrants.

    Finish the following incomplete Ruby implementation of this algorithm and save it as triangle.rb. You only need to supply the parameters to the recursive procedure calls. You should not add any other additional code. If you do this correctly, you will be able to reproduce the image shown above, by calling start_triangle(256,"blue") after loading your source file. You should note that when you specify drawing coordinates for the canvas, the top left corner is the origin (0,0), x increases as you go from left to right, but y increases as you go from top to bottom.

    HINT: You need to figure out the top-left corner and size for each of the other three quadrants and fill them in for the parameters for the three recursive calls.

    # This function initializes a RubyLabs Canvas, colors it color, and
    # then calls the recursive function triangle to do all the work
    def start_triangle(size, color)
       size = size.round()
       Canvas.init(size+2, size+2, "SierpinskisTriangle")
       Canvas::Rectangle.new(1, 1, size+1, size+1,
                            :width => 0, :fill => color)
       triangle(0, 0, size)
    end
    
    # draw a Sierpinski triangle with top left at (x,y) and 
    # with height and width of size
    def triangle(x, y, size)
       # stop when the size gets smaller than 2 (since we can't subdivide a pixel)
       return if size < 2
    
       half = size / 2.0
       draw_square(x,y,half)
    
       # recursively repeat the triangle
       # for each of the other three quadrants
       triangle( , , )  # Fill in the missing parameters of this call!
       triangle( , , )  # Fill in the missing parameters of this call!
       triangle( , , )  # Fill in the missing parameters of this call!
    end
    
    def draw_square(x,y,half)
       # draw a white square in the upper left quadrant
       Canvas::Rectangle.new(1 + x,
                             1 + y,
                             1 + x + half,
                             1 + y + half,
                             :width => 0, :fill => "white")
    end
    
  3. Another fractal image, known as Sierpinski's Carpet, is shown at right. It can be rendered in a manner similar to the drawing of Sierpinski's Triangle shown above:

    1. Return nilif the image is too small to be visibly subdivided.
    2. Otherwise, consider the square being divided up into nine equally-sized square sectors (three wide by three high).
    3. Draw a square in the central sector.
    4. Recursively draw a Sierpinski carpet in each of the other eight sectors.

    In the file carpet.rb, place Ruby functions start_carpet(size,color) and carpet(x,y,size) that render a Sierpinski's Carpet based on the procedure described above. Calling start_carpet(243,"blue") should result in the figure shown at right.


  4. Come up with an algorithm to draw another cool looking fractal image. Save your code in my_fractal.rb.