From the pentive? fractal it is clearly possible to develop some interesting "textured" shapes, here I produce an approximate circle from a set of rotations.
########################################################
# A Pentive fractal implemented using a
# Lindenmayer System in ruby-processing by Martin Prout
########################################################
require 'pentive'
class Pentive_Test < Processing::App
attr_reader :pentive,:points, :production
def setup
size(500, 500)
@pentive = Pentive.new(0, 0)
@production = pentive.create_grammar(6)
@points = pentive.translate_rules(production)
no_loop()
end
def draw_element()
stroke(255)
points.each do |tmp|
line(*tmp)
end
end
def draw()
background(0)
translate(width/2, height/2)
10.times do
rotate(Math::PI/180 * 36)
draw_element()
end
save_frame("/home/tux/advance.png")
end
end
Experiments with ruby-processing (processing-2.2.1) and JRubyArt for processing-3.0
Friday, 12 February 2010
Developing the shapes
Labels:
developing shapes,
fractal art
Thursday, 11 February 2010
A Pentive? Fractal
The pentive fractal is another space filling fractal that I found over on a fractint site again for the grammar generator see my Cesàro fractal.
########################################################
# A Pentive fractal implemented using a
# Lindenmayer System in ruby-processing by Martin Prout
########################################################
require 'pentive'
class Pentive_Test < Processing::App
attr_reader :pentive,:points, :production
def setup
size(600, 400)
@pentive = Pentive.new(width/95, height*0.9)
@production = pentive.create_grammar(8)
@points = pentive.translate_rules(production)
no_loop()
end
def draw()
background(0)
stroke(255)
points.each do |tmp|
line(*tmp)
end
end
end
####################################################
# The Pentive? fractal
####################################################
class Pentive
attr_reader :draw_length, :xpos, :ypos, :theta, :axiom, :grammar, :delta
DELTA = Math::PI/180 * 36 # 36 degrees
def initialize xpos, ypos
@axiom = "Q"
@theta = -DELTA
@grammar = Grammar.new(axiom)
grammar.add_rule("F", "")
grammar.add_rule("P","1-FR3+FS1-FU") # abbreviated grammar 1 = two & 3 = four repeats
grammar.add_rule("Q", "FT1+FR3-FS1+")
grammar.add_rule("R", "1+FP3-FQ1+FT")
grammar.add_rule("S", "FU1-FP3+FQ1-")
grammar.add_rule("T", "+FU1-FP+")
grammar.add_rule("U", "-FQ1+FT-")
@draw_length = 12
@xpos = xpos
@ypos = ypos
end
def create_grammar(gen)
grammar.generate(gen)
end
def translate_rules(prod)
repeats = 1
points = [] # An empty array to store lines as an array of points
prod.scan(/./) do |ch|
case(ch)
when "F"
temp = [xpos, ypos, (@xpos += draw_length * Math.cos(theta)), (@ypos += draw_length * Math.sin(theta))]
points.push(temp)
when "+"
@theta += DELTA * repeats
repeats = 1
when "-"
@theta -= DELTA * repeats
repeats = 1
when '1', '3'
repeats += Integer(ch)
when "P", "Q", "R", "S", "T", "U"
else
puts("character '#{ch}' not in grammar")
end
end
return points
end
end
########################################################
# A Pentive fractal implemented using a
# Lindenmayer System in ruby-processing by Martin Prout
########################################################
require 'pentive'
class Pentive_Test < Processing::App
attr_reader :pentive,:points, :production
def setup
size(600, 400)
@pentive = Pentive.new(width/95, height*0.9)
@production = pentive.create_grammar(8)
@points = pentive.translate_rules(production)
no_loop()
end
def draw()
background(0)
stroke(255)
points.each do |tmp|
line(*tmp)
end
end
end
####################################################
# The Pentive? fractal
####################################################
class Pentive
attr_reader :draw_length, :xpos, :ypos, :theta, :axiom, :grammar, :delta
DELTA = Math::PI/180 * 36 # 36 degrees
def initialize xpos, ypos
@axiom = "Q"
@theta = -DELTA
@grammar = Grammar.new(axiom)
grammar.add_rule("F", "")
grammar.add_rule("P","1-FR3+FS1-FU") # abbreviated grammar 1 = two & 3 = four repeats
grammar.add_rule("Q", "FT1+FR3-FS1+")
grammar.add_rule("R", "1+FP3-FQ1+FT")
grammar.add_rule("S", "FU1-FP3+FQ1-")
grammar.add_rule("T", "+FU1-FP+")
grammar.add_rule("U", "-FQ1+FT-")
@draw_length = 12
@xpos = xpos
@ypos = ypos
end
def create_grammar(gen)
grammar.generate(gen)
end
def translate_rules(prod)
repeats = 1
points = [] # An empty array to store lines as an array of points
prod.scan(/./) do |ch|
case(ch)
when "F"
temp = [xpos, ypos, (@xpos += draw_length * Math.cos(theta)), (@ypos += draw_length * Math.sin(theta))]
points.push(temp)
when "+"
@theta += DELTA * repeats
repeats = 1
when "-"
@theta -= DELTA * repeats
repeats = 1
when '1', '3'
repeats += Integer(ch)
when "P", "Q", "R", "S", "T", "U"
else
puts("character '#{ch}' not in grammar")
end
end
return points
end
end
Labels:
l-system fractal,
ruby processing
MPeano Fractal (Traveling Salesman Problem)
Uses my grammar library see the Cesàro fractal, here I included it in the mpeano.rb file, which is why it didn't need to be separately loaded (omitted for brevity).
########################################################
# A MPeano fractal implemented using a
# Lindenmayer System in ruby-processing by Martin Prout
########################################################
require 'mpeano'
class MPeano_Test < Processing::App
attr_reader :mpeano, :points, :production
def setup
size(600, 600)
@mpeano = MPeano.new(width/2, height*0.95)
@production = mpeano.create_grammar(7)
@points = mpeano.translate_rules(production)
no_loop()
end
def draw()
background(0)
stroke(255)
points.each do |tmp|
line(*tmp)
end
end
end
####################################################
# The MPeano fractal has been used to study the
# Euclidean travelling salesman problem
####################################################
class MPeano
attr_reader :draw_length, :xpos, :ypos, :theta, :axiom, :grammar, :delta
def initialize xpos, ypos
@axiom = "XFF--AFF--XFF--AFF"
@delta = Math::PI/4 # 45 degrees
@theta = delta * 2
@grammar = Grammar.new(axiom)
grammar.add_rule("X", "+!X!FF-BQFI-!X!FF+")
grammar.add_rule("F", "")
grammar.add_rule("Y", "FFY")
grammar.add_rule("A", "BQFI")
grammar.add_rule("B", "AFF")
@draw_length = 8
@xpos = xpos
@ypos = ypos
end
def create_grammar(gen)
grammar.generate(gen)
end
def translate_rules(prod)
points = [] # An empty array to store lines as an array of points
prod.scan(/./) do |ch|
case(ch)
when "F"
temp = [xpos, ypos, (@xpos -= draw_length * Math.cos(theta)), (@ypos -= draw_length * Math.sin(theta))]
points.push(temp)
when "+"
@theta += delta
when "-"
@theta -= delta
when "!"
@delta = -delta
when "I"
@draw_length *= 1/Math.sqrt(2)
when "Q"
@draw_length *= Math.sqrt(2)
when "X", "A", "B"
else
puts("character '#{ch}' not in grammar")
end
end
return points
end
end
########################################################
# A MPeano fractal implemented using a
# Lindenmayer System in ruby-processing by Martin Prout
########################################################
require 'mpeano'
class MPeano_Test < Processing::App
attr_reader :mpeano, :points, :production
def setup
size(600, 600)
@mpeano = MPeano.new(width/2, height*0.95)
@production = mpeano.create_grammar(7)
@points = mpeano.translate_rules(production)
no_loop()
end
def draw()
background(0)
stroke(255)
points.each do |tmp|
line(*tmp)
end
end
end
####################################################
# The MPeano fractal has been used to study the
# Euclidean travelling salesman problem
####################################################
class MPeano
attr_reader :draw_length, :xpos, :ypos, :theta, :axiom, :grammar, :delta
def initialize xpos, ypos
@axiom = "XFF--AFF--XFF--AFF"
@delta = Math::PI/4 # 45 degrees
@theta = delta * 2
@grammar = Grammar.new(axiom)
grammar.add_rule("X", "+!X!FF-BQFI-!X!FF+")
grammar.add_rule("F", "")
grammar.add_rule("Y", "FFY")
grammar.add_rule("A", "BQFI")
grammar.add_rule("B", "AFF")
@draw_length = 8
@xpos = xpos
@ypos = ypos
end
def create_grammar(gen)
grammar.generate(gen)
end
def translate_rules(prod)
points = [] # An empty array to store lines as an array of points
prod.scan(/./) do |ch|
case(ch)
when "F"
temp = [xpos, ypos, (@xpos -= draw_length * Math.cos(theta)), (@ypos -= draw_length * Math.sin(theta))]
points.push(temp)
when "+"
@theta += delta
when "-"
@theta -= delta
when "!"
@delta = -delta
when "I"
@draw_length *= 1/Math.sqrt(2)
when "Q"
@draw_length *= Math.sqrt(2)
when "X", "A", "B"
else
puts("character '#{ch}' not in grammar")
end
end
return points
end
end
Labels:
MPeano fractal,
ruby processing
Wednesday, 10 February 2010
DavidTour fractal
For the grammar.rb library see my Cesàro fractal (here it was included in the davidtour.rb file which is why it didn't need to be separately loaded, Grammar code omitted for brevity).
########################################################
# A David Tour fractal implemented using a
# Lindenmayer System in ruby-processing by Martin Prout
########################################################
require 'davidtour'
class David_Test < Processing::App
attr_reader :david, :points, :production
def setup
size(800, 900)
@david = DavidTour.new(width * 0.6, height/4)
@production = david.create_grammar(5)
@points = david.translate_rules(production)
no_loop()
end
def draw()
background(0)
stroke(255)
points.each do |tmp|
line(*tmp)
end
end
end
####################################################
# The DavidTour fractal has been used to study the
# Euclidean travelling salesmam problem
####################################################
class DavidTour
attr_reader :draw_length, :xpos, :ypos, :theta, :axiom, :grammar
DELTA = Math::PI/3 # 60 degrees
def initialize xpos, ypos
@axiom = "FX-XFX-XFX-XFX-XFX-XF"
@theta = 0
@grammar = Grammar.new(axiom)
grammar.add_rule("F", "!F!-F-!F!")
grammar.add_rule("X", "!X")
@draw_length = 15
@xpos = xpos
@ypos = ypos
end
def create_grammar(gen)
@draw_length *= @draw_length * 0.5**gen
grammar.generate(gen)
end
def translate_rules(prod)
swap = false
points = [] # An empty array to store lines as an array of points
prod.scan(/./) do |ch|
case(ch)
when 'F'
temp = [xpos, ypos, (@xpos += draw_length * Math.cos(theta)), (@ypos -= draw_length * Math.sin(theta))]
points.push(temp)
when '+'
@theta += (DELTA)
when '-'
@theta += (swap ? DELTA : -DELTA)
when '!'
swap = !swap
when 'X'
else
puts("character '#{ch}' not in grammar")
end
end
return points
end
end
########################################################
# A David Tour fractal implemented using a
# Lindenmayer System in ruby-processing by Martin Prout
########################################################
require 'davidtour'
class David_Test < Processing::App
attr_reader :david, :points, :production
def setup
size(800, 900)
@david = DavidTour.new(width * 0.6, height/4)
@production = david.create_grammar(5)
@points = david.translate_rules(production)
no_loop()
end
def draw()
background(0)
stroke(255)
points.each do |tmp|
line(*tmp)
end
end
end
####################################################
# The DavidTour fractal has been used to study the
# Euclidean travelling salesmam problem
####################################################
class DavidTour
attr_reader :draw_length, :xpos, :ypos, :theta, :axiom, :grammar
DELTA = Math::PI/3 # 60 degrees
def initialize xpos, ypos
@axiom = "FX-XFX-XFX-XFX-XFX-XF"
@theta = 0
@grammar = Grammar.new(axiom)
grammar.add_rule("F", "!F!-F-!F!")
grammar.add_rule("X", "!X")
@draw_length = 15
@xpos = xpos
@ypos = ypos
end
def create_grammar(gen)
@draw_length *= @draw_length * 0.5**gen
grammar.generate(gen)
end
def translate_rules(prod)
swap = false
points = [] # An empty array to store lines as an array of points
prod.scan(/./) do |ch|
case(ch)
when 'F'
temp = [xpos, ypos, (@xpos += draw_length * Math.cos(theta)), (@ypos -= draw_length * Math.sin(theta))]
points.push(temp)
when '+'
@theta += (DELTA)
when '-'
@theta += (swap ? DELTA : -DELTA)
when '!'
swap = !swap
when 'X'
else
puts("character '#{ch}' not in grammar")
end
end
return points
end
end
Labels:
fractal,
LSystems,
travelling salesman
Tuesday, 2 February 2010
The Best of Both Worlds (combining PeasyCam and control_panel
This ruby processing sketch shows how to get the best of both worlds; the smooth easily setup PeasyCam, that you can use the scroll-wheel to zoom, and mouse to drag, and the possible fine grain control of a control panel. In this example I have initially disabled mouse control; use the button to toggle mouse control on or off. Use the control panel slider to set off the rotation or the freeze! button (to stop the rotation). If you only want fine grain rotation (cf. continuous rotation with the slider) then you will need get the camera to remember state (I believe Quark has done this in vanilla processing). If you are really keen you could also implement a slider to control the zoom of the peasy cam (in place of the mouse-wheel).
load_libraries 'PeasyCam', 'control_panel'
import 'peasy'
attr_reader :cam, :x_rotate, :y_rotate, :z_rotate, :controlled
def setup()
size(200, 200, P3D)
configure_panel()
@controlled = true
configure_camera()
end
def configure_camera()
@cam = PeasyCam.new(self, 100)
cam.set_minimum_distance(50)
cam.set_maximum_distance(500)
mouse_control()
end
def configure_panel()
control_panel do |c|
c.slider(:x_rotate, -1.0..1.0, 0.0)
c.slider(:y_rotate, -1.0..1.0, 0.0)
c.slider(:z_rotate, -1.0..1.0, 0.0)
c.button(:freeze!)
c.button(:mouse_control)
end
end
def freeze!()
@x_rotate = 0.0
@y_rotate = 0.0
@z_rotate = 0.0
end
def mouse_control() # toggle mouse controlled camera
cam.set_mouse_controlled(!controlled)
@controlled = !controlled
end
def draw()
cam.rotate_x(x_rotate/100)
cam.rotate_y(y_rotate/100)
cam.rotate_z(z_rotate/100)
rotate_x(-0.5)
rotate_y(-0.5)
background(0)
fill(255, 0, 0)
box(30)
push_matrix()
translate(0, 0, 20)
fill(0, 0, 255)
box(5)
pop_matrix()
end
load_libraries 'PeasyCam', 'control_panel'
import 'peasy'
attr_reader :cam, :x_rotate, :y_rotate, :z_rotate, :controlled
def setup()
size(200, 200, P3D)
configure_panel()
@controlled = true
configure_camera()
end
def configure_camera()
@cam = PeasyCam.new(self, 100)
cam.set_minimum_distance(50)
cam.set_maximum_distance(500)
mouse_control()
end
def configure_panel()
control_panel do |c|
c.slider(:x_rotate, -1.0..1.0, 0.0)
c.slider(:y_rotate, -1.0..1.0, 0.0)
c.slider(:z_rotate, -1.0..1.0, 0.0)
c.button(:freeze!)
c.button(:mouse_control)
end
end
def freeze!()
@x_rotate = 0.0
@y_rotate = 0.0
@z_rotate = 0.0
end
def mouse_control() # toggle mouse controlled camera
cam.set_mouse_controlled(!controlled)
@controlled = !controlled
end
def draw()
cam.rotate_x(x_rotate/100)
cam.rotate_y(y_rotate/100)
cam.rotate_z(z_rotate/100)
rotate_x(-0.5)
rotate_y(-0.5)
background(0)
fill(255, 0, 0)
box(30)
push_matrix()
translate(0, 0, 20)
fill(0, 0, 255)
box(5)
pop_matrix()
end
Labels:
control panel,
PeasyCam library,
ruby processing
Subscribe to:
Posts (Atom)
Followers
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