[SUMMARY] Mexican Blanket (#127)

Discussion in 'Ruby' started by Ruby Quiz, Jun 14, 2007.

  1. Ruby Quiz

    Ruby Quiz Guest

    Several solutions to this quiz called out to RMagick to draw pictures of their
    work. That made for some pretty output. One such solution was from Justin
    Ethier and I want to take a look at that code.

    Justin observed that each row of the pattern is just the previous row shifted
    over one pixel. In order to build those rows, Justing decided to just build one
    long pattern and slice it as needed. Here's that chunk of code:

    def create_gradient(colors, width=5)
    pattern = []

    for i in 0...(width)
    (width-i).times { pattern.push(colors[0]) }
    (i+1).times { pattern.push(colors[1]) }
    end

    for i in 0...(width)
    (i+1).times { pattern.push(colors[2]) }
    (width-i-1).times { pattern.push(colors[1]) }
    end

    pattern
    end

    # ...

    You pass this method an Array of three colors and a width for a full band of
    color. It begins by fading the first color into the second by iteratively
    adding thinner and thinner lines to the gradient pattern. It then repeats the
    process in reverse to fade the second color into the third.

    Justin's blankets also include solid color bands created by the following
    method:

    # ...

    def create_solid(colors, width)
    pattern = []
    for color in colors
    width.times { pattern.push(color) }
    end
    pattern
    end

    # ...

    This methods works exactly like create_gradient() except there's no blending of
    colors.

    With the pieces to create the structure in place, we are now ready for some
    rendering code:

    # ...

    def draw_ascii(pattern, width)
    for i in 0...(pattern.size-width+1)
    puts pattern.slice(i, width).join
    end
    end

    # ...

    As you can see, generating the ASCII output is trivial. The long pattern is
    simply divided into a moving window of width slices. Each slice is then printed
    as one row of output.

    RMagick rendering takes a little more work, but still isn't hard:

    # ...

    require 'RMagick'
    include Magick

    def draw(filename, pattern, width, height)
    canvas = Magick::ImageList.new
    canvas.new_image(width, height, Magick::HatchFill.new('white', 'white'))
    pts = Magick::Draw.new

    for y in 0... height
    line = pattern.slice(y, width)

    x = 0
    for color in line
    pts.fill(color)
    pts.point(x, y)
    x = x + 1
    end
    end

    pts.draw(canvas)
    canvas.write(filename)
    end

    # ...

    This method begins by preparing a canvas on which it can draw points. From
    there it does the same looping over the pattern we saw earlier, but this time
    points are plotted on the canvas. When all the marks have been made, the image
    is flushed to a file on the disk.

    The last bit of code puts the generators and renderers to work:

    # ...
    draw_ascii(create_gradient(['R', 'B', 'Y']), 28)

    mex_flag = create_solid(['rgb(0, 64, 0)', 'white', 'red'], 5)
    border = create_solid(['rgb(0, 64, 0)'], 25)

    pattern = create_gradient(['red', 'blue', 'yellow'])
    pattern = pattern + mex_flag
    pattern = pattern + border
    pattern = pattern + create_gradient(['black', 'red', 'orange'])
    pattern = pattern + border
    pattern = pattern + mex_flag.reverse
    pattern = pattern + create_gradient(['red', 'purple', 'black'], 8)
    draw("mexican_blanket.jpg", pattern, 100, 200)

    You can see here that the ASCII renderer is fed a trivial pattern created from a
    single gradient. The pattern built for the image file is more complex,
    combining several different patterns. In both cases though, it's a single call
    to the drawing routines we examined above to show results.

    My thanks to all the weavers. I'll bet you never knew you had such a talent for
    fabric.

    Tomorrow we will try some non-traditional arithmetic...
    Ruby Quiz, Jun 14, 2007
    #1
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. George Young

    blanket except clause -- best practice?

    George Young, Oct 28, 2003, in forum: Python
    Replies:
    3
    Views:
    400
    John J. Lee
    Oct 29, 2003
  2. RGK

    Blanket font setting?

    RGK, Sep 18, 2008, in forum: Python
    Replies:
    1
    Views:
    231
  3. Ruby Quiz

    [QUIZ] Mexican Blanket (#127)

    Ruby Quiz, Jun 8, 2007, in forum: Ruby
    Replies:
    11
    Views:
    163
    Ivo Dancet
    Jun 12, 2007
  4. Jesse Edelstein

    [QUIZ][SOLUTION] Mexican Blanket (#127)

    Jesse Edelstein, Jun 10, 2007, in forum: Ruby
    Replies:
    1
    Views:
    79
    Jesse Edelstein
    Jun 10, 2007
  5. Ari Brown
    Replies:
    1
    Views:
    83
    Harry Kakueki
    Jun 18, 2007
Loading...

Share This Page