Dan Mayer over at devver.net has kindly analysed and re-factored my penrose_snowflake with caliper (something I've never heard of but then I'm not really in the community, just ploughing my own furrow). He also extended my code in an interesting way to produce a "snowflake screensaver" which labours a bit.
Well I tried out Dans refactoring on my own code (which I had already changed to have a separate grammar library). Here is my revised penrose_snowflake.rb (requires grammar.rb and runs with penrose.rb) incorporating some additional refactoring, which you may or may not like depending on your view of the ternary operator (my multiplier has fewer lines of code and is 4% faster according to my benchmark test). However I have since come up with a different version which I have now used to replace my original posting!!! I think the new version will come into its own for my bracketed L-Systems and my Island fractal which is next on the list for refactoring.
class PenroseSnowflake
include Processing::Proxy
attr_accessor :axiom, :grammar, :start_length, :theta, :production, :draw_length,
:repeats, :xpos, :ypos
DELTA = (Math::PI/180) * 18.0 # convert degrees to radians
def initialize
@axiom = "F3-F3-F3-F3-F"
@grammar = Grammar.new axiom
grammar.add_rule "F", "F3-F3-F45-F++F3-F"
@start_length = 450.0
@theta = 0
@xpos = width * 0.8
@ypos = height * 0.95
@production = axiom
@draw_length = start_length
end
##############################################################################
# Not strictly in the spirit of either processing or L-Systems in my iterate
# function I have ignored the processing translate/rotate functions in favour
# of the direct calculation of the new x and y positions, thus avoiding such
# affine transformations.
##############################################################################
def render()
repeats = 1
production.each_char do |element|
case element
when 'F'
line(xpos, ypos, (@xpos -= multiplier(repeats, :cos)), (@ypos += multiplier(repeats, :sin)))
repeats = 1
when '+'
@theta += DELTA * repeats
repeats = 1
when '-'
@theta -= DELTA * repeats
repeats = 1
when '3', '4', '5'
repeats += Integer(element)
else
puts "Character '#{element}' is not in grammar"
end
end
end
##############################
# create grammar from axiom and
# rules (adjust scale)
##############################
def create_grammar(gen)
@draw_length *= 0.4**gen
@production = grammar.generate gen
end
def multiplier(repeats, type)
value = draw_length * repeats
(type == :cos)? value * Math.cos(theta) : value * Math.sin(theta)
end
end
Experiments with ruby-processing (processing-2.2.1) and JRubyArt for processing-3.0
Thursday, 14 January 2010
Subscribe to:
Post Comments (Atom)
Followers
Blog Archive
-
▼
2010
(73)
-
▼
January
(14)
- Hello Peasy in ruby processing (a simple PeasyCam ...
- Using the PeasyCam library in ruby-processing
- 3D Hilbert Using LSystems and ruby-processing
- Two dimensional Hilbert fractal with LSystems and ...
- Fern Fractal Using LSystems (includes a subtle col...
- Using a symbolic grammar for LSystems ruby-processing
- Islands in ruby processing using my grammar library
- Refactoring my Penrose Snowflake
- A 3D Plant using L-Systems and ruby-processing
- Another control panel example with odd turtle turns
- Adding some controls to Sierpinski sketch
- A Sierpinski Variant using L-Systems and ruby proc...
- An interactive l-system sketch using the Control P...
- Checking the probabilities
-
▼
January
(14)
About Me
- monkstone
- I have developed JRubyArt and propane new versions of ruby-processing for JRuby-9.1.5.0 and processing-3.2.2
No comments:
Post a Comment