Forum: Ruby [QUIZ] Fractals (#125)

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
7fd73acc52ca674305ae5103c1050116?d=identicon&s=25 Jim Truher (Guest)
on 2007-05-30 04:29
(Received via mailing list)
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
This topic is locked and can not be replied to.