xxxxxxxxxx
// L-SYSTEMS:
// https://en.wikipedia.org/wiki/L-system
//
// this p5 sketch takes the turtle we created in the last
// project and *automates* the drawing based on a Lindenmayer
// (or L-) system. L-systems are often used in procedural
// graphics to make natural, geometric, or interesting 'fractal-style'
// patterns.
//
// your tasks:
// (1) take a look at the L-system implemented here, and see if you
// can expand upon it to do some automatic, cool, geometric drawing.
// use the turtle that you retooled from the previous sketch as the
// drawing engine.
// hint: google L-systems. there are lots of them out there.
// another hint: you can use non-drawing symbols as symbolic
// placeholders to create really complex patterns.
var thestring = '';
var therules = [];
var numproductions, t, d;
var isDrawing = true;
thestring = 'X'; // the starting string ("axiom")
therules[0] = ['X', 'F[+X][-X]FX'];
therules[1] = ['F', 'FF'];
numproductions = 7;
t = 25.7; // turn amount
d = 3;
var ptr = 0;
var osc, rev;
var thefreq;
// graphics stuff:
// a simple version of Papert's turtle
var x = [];
var y = [];
var a = [];
var lpf = 10; // letters per frame
function setup() {
createCanvas(windowWidth, windowHeight);
init();
// triple loop:
for(let i = 0;i<numproductions;i++)
{
var outstring = '';
for(let j = 0;j<thestring.length;j++)
{
for(let k = 0;k<therules.length;k++)
{
var ismatch = 0;
if(thestring.charAt(j)==therules[k][0]) // MATCH
{
outstring+=therules[k][1]; // copy of the second half
ismatch=1;
break;
}
}
if(ismatch==0) outstring+=thestring.charAt(j);
}
thestring=outstring;
}
console.log(thestring);
// sound:
osc = new p5.Oscillator('sine');
osc.freq(thefreq);
osc.amp(0.1);
osc.start();
rev = new p5.Reverb();
rev.process(osc, 3, 2);
}
function draw() {
var c;
for(let i = 0;i<lpf;i++)
{
c = thestring.charAt(ptr);
if(ptr<thestring.length) doTurtle(c);
ptr = ptr+1;
}
}
function init() {
background("YellowGreen");
x = [];
y = [];
a = [];
x[0] = width/2;
y[0] = height + 120;
a[0] = PI*3/2;
thefreq = 300;
}
function doTurtle(k) {
if (isDrawing){
let theamp = 0;
if(k=='c') init();
if(k=='F') // draw forward
{
strokeWeight(3);
stroke("DarkOliveGreen");
let x1 = x[x.length-1] + d*cos(a[a.length-1]);
let y1 = y[y.length-1] + d*sin(a[a.length-1]);
line(x[x.length-1], y[y.length-1], x1, y1);
x[x.length-1] = x1;
y[y.length-1] = y1;
theamp = 0.3;
}
if(k=='B') // draw circle
{
stroke(255, 0, 255);
ellipse(x[x.length-1], y[y.length-1], d, d);
theamp = 0.1;
}
if(k=='+') // turn right
{
a[a.length-1]+=radians(t);
thefreq*=1.75;
}
if(k=='-') // turn left
{
a[a.length-1]-=radians(t);
thefreq/=1.75;
}
if(k=='[') // start branch
{
x.push(x[x.length-1]);
y.push(y[y.length-1]);
a.push(a[a.length-1]);
}
if(k==']') // end branch
{
x.pop();
y.pop();
a.pop();
}
osc.freq(thefreq);
osc.amp(theamp, 0.04);
}
}