Diff from Recursion-toy-like vines with Pen by uiae (04 Sep'11 20:16) to Re: Recursion-toy-like vines with Pen by vividsnow (05 Sep'11 21:41)
name
Re: Recursion-toy-like vines with Pen
description
code
(
t = Bus.audio(Server.default, 2);
SynthDef(\gr, { |freq = 300, mod_freq = 300, amp = 1, amp_freq = 1|
Out.ar(t, PMOsc.ar(Lag.kr(freq), Lag.kr(mod_freq), 2, mul: SinOsc.ar(amp_freq, mul: Lag.kr(amp * AmpCompA.kr(freq))) ) ! 2)
}).add;
{ Out.ar(0, Limiter.ar(In.ar(t, 2))) }.play;
)
(
var win, view;
var run = true;
q = ();
q.branches = List[];
q.minWanderStep = 1.0184;
q.maxWanderStep = 0.1702;
q.minGrowthRate = 10.6214;
q.maxGrowthRate = 11.8251;
q.minShrinkRate = 0.99656;
q.maxShrinkRate = 0.91265;
q.branchProbability = 0.05;
q.minDivergence = 1.3268;
q.maxDivergence = 1.3885;
q.maxConcurrent = 500;
q.numBranches = 6;
q.minRadius = 0.15;
q.maxRadius = 70;
q.makeBranch = {
arg env, x, y, theta, radius, scale = 1.0, generation = 1;
(
sy: Synth(\gr),
x: x,
y: y,
ox:x,
oy: y,
x1: nil, x2: nil,
y1: nil, y2: nil,
scale: 1.0,
theta: theta,
oTheta:theta,
radius:radius,
generation:1,
growing:true,
age:0,
wanderStep: rrand(q.minWanderStep, q.maxWanderStep),
growthRate: rrand(q.minGrowthRate, q.maxGrowthRate),
shrinkRate: rrand(q.minShrinkRate, q.maxShrinkRate),
fRender: {
arg that, context;
var scale, radius;
if(that.growing,
{
scale = that.scale;
radius = that.radius * scale;
// Draw outline
Pen.line(that.ox@that.oy,that.x@that.y);
// not in qt...
if((GUI.scheme == "CocoaGUI") and: (radius > 5.0), {
Pen.setShadow(1@1, scale, Color.new(0,0,0,0.05));
});
Pen.width = radius + scale;
Pen.strokeColor = Color.black;
Pen.capStyle = 1; //round
Pen.stroke();
// Draw fill
Pen.line(that.ox@that.oy, that.x@that.y);
Pen.width = radius;
Pen.strokeColor = Color.white;
Pen.capStyle = 1; //round
Pen.stroke();
});
},
fUpdate: {
arg that;
var theta, scale, radius, branch, offset;
if(that.growing,
{
that.ox = that.x;
that.oy = that.y;
that.oTheta = that.theta;
that.theta = that.theta + rrand(that.wanderStep * -1,
that.wanderStep);
that.x = that.x + (cos(that.theta)
* that.growthRate * that.scale);
that.y = that.y + (sin(that.theta)
* that.growthRate * that.scale);
that.scale = that.scale * that.shrinkRate;
if(
(q.branches.size < q.maxConcurrent)
and:
(1.0.rand < q.branchProbability),
{
offset = rrand(q.minDivergence,
q.maxDivergence);
theta = that.theta
+ (offset * [1,-1].choose);
scale = that.scale * 0.95;
radius = that.radius * scale;
branch = q.makeBranch(
that.x, that.y, theta, radius, scale);
branch.generation = that.generation + 1;
q.branches.add(branch);
});
that.age = (that.age + 1);
// Change freq
//that.sy.set(\freq, sqrt(that.ox.squared + that.ox.squared).linlin(0,sqrt(350.squared * 2),50,350));
that.sy.set(\freq, that.ox.linlin(0,350,10,550));
that.sy.set(\mod_freq, that.oy.linlin(0,350,10,550));
that.sy.set(\amp, that.radius.linlin(0.15,70,0.1,1));
that.sy.set(\amp_freq, that.age.reciprocal);
if((that.radius * that.scale) <= q.minRadius, {
that.growing = false;
});
that.age = (thatsy.agfre + 1)e;
});
})
}
)
};
q.makeRecursion = {
arg env;
(
//started: false,
fReset: { q.branches.do{|i| i.sy.free; }; },
fSpawn: {
arg env, x, y;
var theta, radius;
q.branches = List[];
q.numBranches.do{
arg i;
theta = (i / q.numBranches) * 2pi;
radius = q.maxRadius;
q.branches.add(q.makeBranch(x, y, theta - (pi/2), radius));
}
},
fUpdate: {
arg env;
var index;
var numBranches = q.branches.size;
q.branches.do{
arg branch, i;
branch.fUpdate;
branch.fRender;
};
//strip dead branches
numBranches.do{
|i|
index = numBranches - (i + 1);
if(q.branches[index].growing.not,
{
q.branches.removeAt(index);
})
}
}
)
};
r = q.makeRecursion;
r.fSpawn(350,350);
win = Window(
"grow! (click to restart)", Rect(10, 10, 700, 700)
);
win.onClose = { r.fReset; run = false; };
view = UserView(win, 700@700).drawFunc_({ r.fUpdate }).clearOnRefresh_(false).mouseDownAction_({ |v,x,y| view.clearDrawing; r.fReset; r.fSpawn(x,y) });
win.front;
{ while { run } { win.refresh; 0.05.wait } }.fork(AppClock)
)
category tags
gui, code fork, sonification
ancestors
1-14