{
   "labels" : [
      "gui",
      "code fork",
      "sonification"
   ],
   "code" : "(\r\nt = Bus.audio(Server.default, 2);\r\nSynthDef(\\gr, { |freq = 300, mod_freq = 300, amp = 1, amp_freq = 1| \r\n\tOut.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) \r\n}).add;\r\n{ Out.ar(0, Limiter.ar(In.ar(t, 2))) }.play;\r\n)\r\n\r\n(\r\nvar win, view;\r\nvar run = true;\r\nq = ();\r\n\r\nq.branches = List[];\r\n\r\nq.minWanderStep = 1.0184;\r\nq.maxWanderStep = 0.1702;\r\nq.minGrowthRate = 10.6214;\r\nq.maxGrowthRate = 11.8251;\r\nq.minShrinkRate = 0.99656;\r\nq.maxShrinkRate = 0.91265;\r\nq.branchProbability = 0.05;\r\nq.minDivergence = 1.3268;\r\nq.maxDivergence = 1.3885;\r\nq.maxConcurrent = 50;\r\nq.numBranches = 6;\r\nq.minRadius = 0.15;\r\nq.maxRadius = 70;\r\n\r\n\r\nq.makeBranch = {\r\n\targ env, x, y, theta, radius, scale = 1.0, generation = 1;\r\n \r\n\t(\r\n\t\tsy: Synth(\\gr),\r\n\t\tx: x, \r\n\t\ty: y,\r\n\t\tox:x, \r\n\t\toy: y,\r\n\t\tx1: nil, x2: nil,\r\n\t\ty1: nil, y2: nil,\r\n\t\tscale: 1.0,\r\n\t\ttheta: theta,\r\n\t\toTheta:theta,\r\n\t\tradius:radius,\r\n\t\tgeneration:1,\r\n\t\tgrowing:true,\r\n\t\tage:0,\r\n\t\twanderStep: rrand(q.minWanderStep, q.maxWanderStep),\r\n\t\tgrowthRate: rrand(q.minGrowthRate, q.maxGrowthRate),\r\n\t\tshrinkRate: rrand(q.minShrinkRate, q.maxShrinkRate),\r\n\t\tfRender: {\r\n\t\t\targ that, context;\r\n\t\t\tvar scale, radius;\r\n\t\t\tif(that.growing,\r\n\t\t\t\t{\r\n\t\t\t\t\tscale = that.scale;\r\n\t\t\t\t\tradius = that.radius * scale;\r\n\t\t\t\t\t\r\n\t\t\t\t\t// Draw outline\r\n\t\t\t\t\tPen.line(that.ox@that.oy,that.x@that.y);\r\n\t\t\t\t\t\r\n\t\t\t\t\t// not in qt...\r\n\t\t\t\t\tif((GUI.scheme == \"CocoaGUI\") and: (radius > 5.0), {\r\n\t\t\t\t\t \tPen.setShadow(1@1, scale, Color.new(0,0,0,0.05));\r\n\t\t\t\t\t});\r\n\t\t\t\t\t\r\n\t\t\t\t\tPen.width = radius + scale;\r\n\t\t\t\t\tPen.strokeColor = Color.black;\r\n\t\t\t\t\tPen.capStyle = 1; //round\r\n\t\t\t\t\tPen.stroke();\r\n\t\t\t\t\t\r\n\t\t\t\t\t// Draw fill\r\n\t\t\t\t\tPen.line(that.ox@that.oy, that.x@that.y);\r\n\r\n\t\t\t\t\tPen.width = radius;\r\n\t\t\t\t\tPen.strokeColor = Color.white;\r\n\t\t\t\t\tPen.capStyle = 1; //round\r\n\t\t\t\t\tPen.stroke();\r\n\t\t\t\t});\r\n\t\t},\r\n\t\tfUpdate: {\r\n\t\t\targ that;\r\n\t\t\tvar theta, scale, radius, branch, offset;\r\n\t\t\tif(that.growing,\r\n\t\t\t\t{\r\n\t\t\t\t\tthat.ox = that.x;\r\n\t\t\t\t\tthat.oy = that.y;\r\n\t\t\t\t\tthat.oTheta = that.theta;\r\n\r\n\t\t\t\t\tthat.theta = that.theta + rrand(that.wanderStep * -1,\r\n\t\t\t\t\t\tthat.wanderStep);\r\n\t\t\t\t\t\r\n\t\t\t\t\tthat.x = that.x + (cos(that.theta) \r\n\t\t\t\t\t\t* that.growthRate * that.scale);\r\n\t\t\t\t\tthat.y = that.y + (sin(that.theta) \r\n\t\t\t\t\t\t* that.growthRate * that.scale);\r\n\r\n\t\t\t\t\tthat.scale = that.scale * that.shrinkRate;\r\n\r\n\t\t\t\t\tif(\r\n\t\t\t\t\t\t(q.branches.size < q.maxConcurrent)\r\n\t\t\t\t\t\tand:\r\n\t\t\t\t\t\t(1.0.rand < q.branchProbability),\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\toffset = rrand(q.minDivergence,\r\n\t\t\t\t\t\t\t\tq.maxDivergence);\r\n\t\t\t\t\t\t\ttheta = that.theta \r\n\t\t\t\t\t\t\t+ (offset * [1,-1].choose);\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\tscale = that.scale * 0.95;\r\n\t\t\t\t\t\t\tradius = that.radius * scale;\r\n\r\n\t\t\t\t\t\t\tbranch = q.makeBranch(\r\n\t\t\t\t\t\t\t\tthat.x, that.y, theta, radius, scale);\r\n\r\n\t\t\t\t\t\t\tbranch.generation = that.generation + 1;\r\n\t\t\t\t\t\t\tq.branches.add(branch);\r\n\t\t\t\t\t\t});\r\n\r\n\t\t\t\t\tthat.age = (that.age + 1);\r\n\t\t\t\t\t// Change freq\r\n\t\t\t\t\t//that.sy.set(\\freq, sqrt(that.ox.squared + that.ox.squared).linlin(0,sqrt(350.squared * 2),50,350));\r\n\t\t\t\t\tthat.sy.set(\\freq, that.ox.linlin(0,350,10,550));\r\n\t\t\t\t\tthat.sy.set(\\mod_freq, that.oy.linlin(0,350,10,550));\r\n\t\t\t\t\tthat.sy.set(\\amp, that.radius.linlin(0.15,70,0.1,1));\r\n\t\t\t\t\tthat.sy.set(\\amp_freq, that.age.reciprocal);\r\n\r\n\t\t\t\t\tif((that.radius * that.scale) <= q.minRadius, {\r\n\t\t\t\t\t\tthat.growing = false;\r\n\t\t\t\t\t\tthat.sy.free;\r\n\t\t\t\t\t});\t\t\t\t\t\r\n\t\t\t\t})\r\n\t\t}\r\n\t)\r\n};\r\n\r\nq.makeRecursion = {\r\n\targ env;\r\n\r\n\t(\r\n\t\t//started: false,\r\n\t\tfReset: { q.branches.do{|i| i.sy.free; }; },\r\n\t\tfSpawn: {\r\n\t\t\targ env, x,  y;\r\n\t\t\tvar theta, radius;\r\n\t\t\tq.branches = List[];\r\n\t\t\tq.numBranches.do{\r\n\t\t\t\targ i;\r\n\t\t\t\ttheta = (i / q.numBranches) * 2pi;\r\n\t\t\t\tradius = q.maxRadius;\r\n\t\t\t\tq.branches.add(q.makeBranch(x, y, theta - (pi/2), radius));\r\n\t\t\t}\r\n\t\t},\r\n\t\tfUpdate: {\r\n\t\t\targ env;\r\n\t\t\tvar index;\r\n\t\t\tvar numBranches = q.branches.size;\r\n\t\t\tq.branches.do{\r\n\t\t\t\targ branch, i;\r\n\t\t\t\tbranch.fUpdate;\r\n\t\t\t\tbranch.fRender;\r\n\t\t\t};\r\n\t\t\t//strip dead branches\r\n\t\t\t\r\n\t\t\tnumBranches.do{\r\n\t\t\t\t|i|\r\n\t\t\t\tindex = numBranches - (i + 1);\r\n\t\t\t\tif(q.branches[index].growing.not,\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\tq.branches.removeAt(index);\r\n\t\t\t\t\t})\r\n\t\t\t}\r\n\t\t}\r\n\t)\t\r\n};\r\n\r\nr = q.makeRecursion;\r\nr.fSpawn(350,350);\r\nwin = Window(\"grow! (click to restart)\", Rect(10, 10, 700, 700));\r\nwin.onClose = { r.fReset; run = false; };\r\nview = UserView(win, 700@700).drawFunc_({ r.fUpdate }).clearOnRefresh_(false).mouseDownAction_({ |v,x,y| view.clearDrawing; r.fReset; r.fSpawn(x,y) });\r\nwin.front;\r\n{ while { run } { win.refresh; 0.05.wait } }.fork(AppClock)\r\n)",
   "id" : "1-15",
   "is_private" : null,
   "author" : "vividsnow",
   "name" : "Re: Recursion-toy-like vines with Pen",
   "description" : "some simple sonification of [1-14](http://sccode.org/1-14)",
   "ancestor_list" : [
      "1-14"
   ]
}
