Skip to content

Commit bf5c7ec

Browse files
committed
mycelium
1 parent 69504ac commit bf5c7ec

3 files changed

Lines changed: 115 additions & 11 deletions

File tree

external_library/gem/pbox2d/lib/particle_system.rb

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
module Runnable
44
def run
5-
reject! { |item| item.done }
6-
each { |item| item.display }
5+
reject!(&:done)
6+
each(&:display)
77
end
88
end
99

@@ -14,15 +14,15 @@ class ParticleSystem
1414
def_delegator(:@particles, :empty?, :dead?)
1515

1616
attr_reader :x, :y
17-
17+
1818
def initialize(bd, num, x, y)
1919
@particles = [] # Initialize the Array
20-
@x, @y = x, y # Store the origin point
20+
@x, @y = x, y # Store the origin point
2121
num.times do
2222
self << Particle.new(bd, x, y)
2323
end
2424
end
25-
25+
2626
def add_particles(bd, n)
2727
n.times do
2828
self << Particle.new(bd, x, y)
@@ -37,9 +37,9 @@ class Particle
3737
include Processing::Proxy
3838
TRAIL_SIZE = 6
3939
# We need to keep track of a Body
40-
40+
4141
attr_reader :trail, :body, :box2d
42-
42+
4343
# Constructor
4444
def initialize(b2d, x, y)
4545
@box2d = b2d
@@ -49,12 +49,12 @@ def initialize(b2d, x, y)
4949
# This way we have collisions, but they don't overwhelm the system
5050
make_body(x, y, 0.2)
5151
end
52-
52+
5353
# This function removes the particle from the box2d world
5454
def kill_body
5555
box2d.destroy_body(body)
5656
end
57-
57+
5858
# Is the particle ready for deletion?
5959
def done
6060
# Let's find the screen position of the particle
@@ -64,7 +64,7 @@ def done
6464
kill_body
6565
true
6666
end
67-
67+
6868
# Drawing the box
6969
def display
7070
# We look at each body and get its screen position
@@ -84,7 +84,7 @@ def display
8484
end
8585
end_shape
8686
end
87-
87+
8888
# This function adds the rectangle to the box2d world
8989
def make_body(x, y, r)
9090
# Define and create the body
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
require 'forwardable'
2+
3+
# Here we use our own Vec2D class, until we create a path as an array of TVec2D
4+
# toxis Vec2D. Required to use the ToxicLibsSupport lineStrip2D method.
5+
# further we can and should use power of ruby to make Branch enumerable and
6+
# Forwardable to define which enumerable methods we want to use
7+
class Branch
8+
include Enumerable
9+
extend Forwardable
10+
def_delegators(:@children, :<<, :each, :length)
11+
# variance angle for growth direction per time step
12+
THETA = Math::PI / 6
13+
# max segments per branch
14+
MAX_LEN = 100
15+
# max recursion limit
16+
MAX_GEN = 3
17+
# branch chance per time step
18+
BRANCH_CHANCE = 0.05
19+
# branch angle variance
20+
BRANCH_THETA = Math::PI / 3
21+
attr_reader :position, :dir, :path, :children, :xbound, :speed, :ybound, :app
22+
23+
def initialize(app, pos, dir, speed)
24+
@app = app
25+
@position = pos
26+
@dir = dir
27+
@speed = speed
28+
@path = []
29+
@children = []
30+
@xbound = Boundary.new(0, app.width)
31+
@ybound = Boundary.new(0, app.height)
32+
path << TVec2D.new(pos.x, pos.y)
33+
end
34+
35+
def run
36+
grow
37+
display
38+
end
39+
40+
private
41+
42+
# Note use of both rotate! (changes original) rotate (returns a copy) of Vec2D
43+
def grow
44+
check_bounds(position + (dir * speed)) if path.length < MAX_LEN
45+
@position += (dir * speed)
46+
dir.rotate!(rand(-0.5..0.5) * THETA)
47+
path << TVec2D.new(position.x, position.y)
48+
if (length < MAX_GEN) && (rand < BRANCH_CHANCE)
49+
branch_dir = dir.rotate(rand(-0.5..0.5) * BRANCH_THETA)
50+
self << Branch.new(app, position.copy, branch_dir, speed * 0.99)
51+
end
52+
each(&:grow)
53+
end
54+
55+
def display
56+
app.gfx.lineStrip2D(path)
57+
each(&:display)
58+
end
59+
60+
def check_bounds(pos)
61+
dir.x *= -1 if xbound.exclude? pos.x
62+
dir.y *= -1 if ybound.exclude? pos.y
63+
end
64+
end
65+
66+
# we are looking for excluded values
67+
Boundary = Struct.new(:lower, :upper) do
68+
def exclude?(val)
69+
true unless (lower...upper).cover? val
70+
end
71+
end
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
require 'toxiclibs'
2+
3+
# Simple recursive branching system inspired by mycelium growth
4+
#
5+
# The vanilla processing sketch was part of the SAC 2013 workshop project
6+
# (c) 2013 Karsten Schmidt
7+
# LGPLv3 licensed
8+
# translated to PiCrate by Martin Prout 2018
9+
10+
load_library :branch
11+
12+
attr_reader :gfx, :root
13+
14+
def setup
15+
@gfx = Gfx::ToxiclibsSupport.new(self)
16+
@root = Branch.new(
17+
self,
18+
Vec2D.new(0, height / 2),
19+
Vec2D.new(1, 0),
20+
10.0
21+
)
22+
end
23+
24+
def draw
25+
background(0)
26+
stroke(255)
27+
no_fill
28+
root.run
29+
end
30+
31+
def settings
32+
full_screen
33+
end

0 commit comments

Comments
 (0)