Created
November 30, 2010 14:59
-
-
Save monkstone/721792 to your computer and use it in GitHub Desktop.
A Snake Kolam in ruby-processing demonstrates the use of PGraphicsPDF
This file contains hidden or 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 hidden or 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 hidden or 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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment