This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
############################################################# | |
# library/grammar.rb | |
# Non-stochastic grammar | |
# with unique premise/rules | |
############################################################ | |
class Grammar | |
attr_accessor :axiom, :rules | |
def initialize axiom | |
@axiom = axiom | |
@rules = Hash.new | |
end | |
def add_rule premise, rule | |
rules.store(premise, rule) | |
end | |
########################################## | |
# replace each pre char with a unique rule | |
########################################## | |
def new_production production | |
production.gsub!(/./) { |c| (r = @rules[c]) ? r : c } | |
end | |
########################################## | |
# control the number of iterations | |
# default 0, returns the axiom | |
########################################## | |
def generate repeat = 0 | |
prod = String.new(axiom) # retain original axiom | |
repeat.times do | |
prod = new_production prod | |
end | |
return prod | |
end | |
############################################# | |
# Returns a string thst describes the LSystem | |
############################################# | |
def to_string | |
rule = "Axiom: #{axiom}\nSubstitution Rules:\n" | |
rules.each{|pr| rule << "#{pr[0]} => #{pr[1]}\n"} | |
return rule | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
####################################################### | |
# Lindenmayer System in ruby-processing by Martin Prout | |
# Demonstrates export to PDF format | |
####################################################### | |
require 'snake_kolam' | |
class Kolam_Test < Processing::App | |
load_libraries :grammar, :pdf | |
import "processing.pdf.PGraphicsPDF" | |
attr_reader :snake, :my_font | |
def setup | |
size 900, 900, P2D | |
@snake = SnakeKolam.new | |
snake.create_grammar 4 | |
background(255) | |
hint(ENABLE_NATIVE_FONTS) | |
@my_font = create_font("/usr/share/fonts/truetype/freefont/FreeSans.ttf", 18) # for the benefit linux users | |
# @my_font = create_font(Any suitable ttf font, 18) | |
background 255 | |
stroke 0 | |
render_to_PDF | |
end | |
def render_to_PDF | |
begin_record PDF, "/home/tux/kolam.pdf" # requires an absolute address for output file | |
snake.render # render kolam (NB text does not appear in frame) | |
fill 0 # font fill | |
text_mode(SHAPE) # fonts as shape | |
textFont(my_font, 18) | |
text("Snake Kolam", 300, 40) # title | |
text(snake.to_string, 100, 780) # lsystem values | |
end_record | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
############################ | |
# snake_kolam.rb using l-systems | |
############################ | |
class SnakeKolam | |
include Processing::Proxy | |
attr_accessor :axiom, :start_length, :xpos, :ypos, :grammar, :production, :draw_length, :gen | |
XPOS = 0 | |
YPOS = 1 | |
ANGLE = 2 | |
DELTA = (Math::PI/180) * 90.0 # convert degrees to radians | |
def initialize | |
setup_grammar | |
@start_length = 160.0 | |
@theta = (Math::PI/180) * 90.0 # convert degrees to radians | |
@draw_length = start_length | |
@draw_length = start_length | |
@xpos = width/8 | |
@ypos = height*0.8 | |
end | |
def setup_grammar | |
@axiom = "FX+F+FX+F" | |
@grammar = Grammar.new(axiom) | |
grammar.add_rule("X", "X-F-F+FX+F+FX-F-F+FX") | |
end | |
def render # NB not using affine transforms here | |
turtle = [xpos, ypos, 0.0] | |
production.scan(/./).each do |element| | |
case element | |
when 'F' | |
turtle = draw_line(turtle, draw_length) | |
when '+' | |
turtle[ANGLE] += DELTA # rotate by + theta if going the affine transform route | |
when '-' | |
turtle[ANGLE] -= DELTA # rotate by - theta if going the affine transform route | |
when 'X' # do nothing except recognize 'X' as a word in the L-system grammar | |
else | |
puts "Character '#{element}' is not in grammar" | |
end | |
end | |
end | |
############################## | |
# create grammar from axiom and | |
# rules (adjust scale) | |
############################## | |
def create_grammar(gen) | |
@gen = gen | |
@draw_length *= 0.6**gen | |
@production = @grammar.generate gen | |
end | |
def to_string | |
rule = "Repeats: #{gen}\n" | |
rule << grammar.to_string | |
end | |
private | |
###################################################### | |
# draws line using current turtle and length parameters | |
# returns a turtle corresponding to the new position | |
###################################################### | |
def draw_line(turtle, length) | |
new_xpos = turtle[XPOS] + length * Math.cos(turtle[ANGLE]) | |
new_ypos = turtle[YPOS] + length * Math.sin(turtle[ANGLE]) | |
line(turtle[XPOS], turtle[YPOS], new_xpos, new_ypos) | |
turtle = [new_xpos, new_ypos, turtle[ANGLE]] | |
end | |
end |
No comments:
Post a Comment