# \[QUIZ\] Fractals (#125)

**URL:** <https://www.ruby-forum.com/t/quiz-fractals-125/105454>\
**Category:** Ruby\
**Created:** [May 30, 2007, 4:29am UTC](https://www.ruby-forum.com/t/quiz-fractals-125/105454 "2007-05-30T04:29:13Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![elyod\_72](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/ed655f/32.png) [@elyod\_72](https://www.ruby-forum.com/u/elyod_72)\
**Post date:** [May 30, 2007, 4:29am UTC](https://www.ruby-forum.com/t/quiz-fractals-125/105454/1 "2007-05-30T04:29:13Z")

</div>

First submission and I’m still new at this ruby thing, so please be  
gentle:)

I was interested in studying l-systems a few weeks ago so it was a  
pleasant  
surprise to see something very similar in this quiz prompt. The ‘hard’  
part  
was rebuilding the grammar. I’ve left the original koch curve in there  
as  
an example of how to mess with things. One thing I’m puzzled about is  
that  
generating the strings is (relatively) fast, but writing the image is  
where  
all the slowdown is. I haven’t quite worked that out yet but for now I  
consider this “good enough”.

BEGIN

#usage: fractal.rb [count]  
#count is the iteration count  
require ‘rubygems’  
require ‘RMagick’  
require ‘date’

#shamelessly taken from ruby cookbook (i think)  
class String  
def mgsub(key\_value\_pairs=[].freeze)  
regexp\_fragments = key\_value\_pairs.collect { |k,v| k }  
gsub(Regexp.union(\*regexp\_fragments)) do |match|  
key\_value\_pairs.detect{|k,v| k =~ match}[1]  
end  
end  
end

#Here are the initial conditions  
#Mess with these to get different fractal shapes  
str = “A”  
#rules = [[/A/, ‘B-A-B’], [/B/, ‘A+B+A’]] #koch curve? i  
think  
so  
rules = [[/A/, ‘A-A+A+A-A’]]  
length = 2  
theta = 90

1.upto ARGV[0].to\_i do |i|  
start = Time.now  
curx = 200.0  
cury = 700.0  
dir = 0  
canvas = Magick::Image.new(1024, 768)  
gc = Magick::Draw.new

```
puts "Iteration #{i}"
puts "String is \n\t #{str}"

```

str.each\_byte do |chr|  
prevx = curx  
prevy = cury  
case chr.chr  
when “A”  
curx += length \* Math::cos(dir \* Math::PI / 180)  
cury += length \* Math::sin(dir \* Math::PI / 180)  
gc.line(prevx, prevy, curx, cury)

```
            prevx = curx
            prevy = cury
  when "B"
    curx += length * Math::cos(dir * Math::PI / 180)
    cury += length * Math::sin(dir * Math::PI / 180)
            gc.line(prevx, prevy, curx, cury)

            prevx = curx
            prevy = cury
  when "-"
    dir -= theta
    dir %= 360
  when "+"
    dir += theta
    dir %= 360
end

```

end  
puts “Killer, done with str.each\_byte - pass # #{i}”  
gc.text(15, 15,"#{i}, length of #{length}, theta of #{theta} degrees")  
gc.draw(canvas)  
canvas.write("#{i} - #{Date.today}.gif")  
puts “Iteration #{i} took #{Time.now - start} seconds.”  
unless i == ARGV[0].to\_i  
str = str.mgsub(rules)  
end  
puts str  
end

END
