Created
December 19, 2018 11:17
-
-
Save monkstone/70d046091229c94322cd984da3adb1f3 to your computer and use it in GitHub Desktop.
toxi
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
/** | |
* Simple recursive branching system inspired by mycelium growth | |
* | |
* This file is part of the SAC 2013 workshop project | |
* (c) 2013 Karsten Schmidt | |
* LGPLv3 licensed | |
*/ | |
import toxi.geom.*; | |
import toxi.processing.*; | |
import java.util.*; | |
// max segments per branch | |
int MAX_LEN = 100; | |
// max recursion limit | |
int MAX_GEN = 3; | |
// variance angle for growth direction per time step | |
float THETA = PI/6; | |
// branch chance per time step | |
float BRANCH_CHANCE = 0.05; | |
// branch angle variance | |
float BRANCH_THETA = PI/3; | |
ToxiclibsSupport gfx; | |
Branch root; | |
// switch to ensure growth remains in window bounds | |
boolean doWrap = true; | |
void setup() { | |
size(1280, 600); | |
gfx = new ToxiclibsSupport(this); | |
root = new Branch(new Vec2D(0, height/2), new Vec2D(1, 0), 10, THETA); | |
} | |
void draw() { | |
background(0); | |
stroke(255); | |
noFill(); | |
root.grow(); | |
root.draw(); | |
} | |
class Branch { | |
Vec2D currPos; | |
Vec2D dir; | |
List<Vec2D> path = new ArrayList<Vec2D>(); | |
List<Branch> children = new ArrayList<Branch>(); | |
float speed; | |
float theta; | |
Branch(Vec2D p, Vec2D d, float s, float t) { | |
currPos = p; | |
dir = d; | |
speed = s; | |
theta = t; | |
path.add(p.copy()); | |
} | |
void grow() { | |
if (path.size() < MAX_LEN) { | |
if (doWrap) { | |
Vec2D newPos = currPos.add(dir.scale(speed)); | |
if (newPos.x < 0 || newPos.x > width) dir.x *= -1; | |
if (newPos.y < 0 || newPos.y > height) dir.y *= -1; | |
} | |
currPos.addSelf(dir.scale(speed)); | |
dir.rotate(random(-0.5, 0.5) * THETA); | |
path.add(currPos.copy()); | |
if (children.size() < MAX_GEN && random(1) < BRANCH_CHANCE) { | |
Vec2D branchDir = dir.getRotated(random(-0.5, 0.5) * BRANCH_THETA); | |
Branch b = new Branch(currPos.copy(), branchDir, speed * 0.99, theta); | |
children.add(b); | |
} | |
} | |
for (Branch c : children) { | |
c.grow(); | |
} | |
} | |
void draw() { | |
gfx.lineStrip2D(path); | |
for (Branch c : children) { | |
c.draw(); | |
} | |
} | |
} |
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
#!/usr/bin/env jruby | |
require 'picrate' | |
require 'toxiclibs' | |
# max segments per branch | |
MAX_LEN = 100 | |
# max recursion limit | |
MAX_GEN = 3 | |
# variance angle for growth direction per time step | |
THETA = Math::PI / 6 | |
# branch chance per time step | |
BRANCH_CHANCE = 0.5 | |
# branch angle variance | |
BRANCH_THETA = Math::PI / 3 | |
# Simple recursive branching system inspired by mycelium growth | |
# | |
# This file is part of the SAC 2013 workshop project | |
# (c) 2013 Karsten Schmidt | |
# LGPLv3 licensed | |
class Mycelium < Processing::App | |
attr_reader :gfx, :root, :doWrap | |
def setup | |
@doWrap = true | |
@gfx = Gfx::ToxiclibsSupport.new(self) | |
@root = Branch.new(Vec2D.new(0, height / 2), Vec2D.new(1, 0), 10.0, THETA) | |
end | |
def draw | |
background(0) | |
stroke(255) | |
noFill | |
root.grow | |
root.draw | |
root.run | |
end | |
def settings | |
size(1280, 600) | |
end | |
end | |
Mycelium.new | |
class Branch | |
include Processing::Proxy | |
attr_reader :currPos, :dir, :path, :children, :generation, :speed, :theta | |
def initialize(p, d, s, t) | |
@currPos = p | |
@dir = d | |
@speed = s | |
@theta = t | |
@path ||= [] | |
@children ||= [] | |
path << TVec2D.new(p.x, p.y) | |
end | |
def grow | |
if path.length < MAX_LEN | |
if doWrap | |
newPos = currPos + (dir * speed) | |
dir.x *= -1 if (newPos.x < 0 || newPos.x > width) | |
dir.y *= -1 if (newPos.y < 0 || newPos.y > height) | |
end | |
end | |
@currPos += (dir * speed) | |
dir.rotate!(rand(-0.5..0.5) * THETA) | |
path << TVec2D.new(currPos.x, currPos.y) | |
if (children.length < MAX_GEN) && (rand < BRANCH_CHANCE) | |
branchDir = dir.rotate(rand(-0.5..0.5) * BRANCH_THETA) | |
children << Branch.new(currPos.copy, branchDir, speed * 0.99, theta) | |
end | |
end | |
def draw | |
gfx.lineStrip2D(path) | |
end | |
def run | |
children(&:grow) | |
children(&:draw) | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment