Public
Edited
Aug 9, 2023
1 fork
Insert cell
Insert cell
container = container_from(canvas);
Insert cell
sketch = function( p ) {

//adapted from R. Luke DuBois' example

// TURTLE STUFF:
let x, y; // the current position of the turtle
let currentangle = 0; // which way the turtle is pointing
let step = 53.3; // how much the turtle moves with each 'F'
let angle = 90; // how much the turtle turns with a '-' or '+'

// LINDENMAYER STUFF (L-SYSTEMS)
let thestring = 'A'; // "axiom" or start of the string
let numloops = 5; // how many iterations to pre-compute
let therules = []; // array for rules
therules[0] = ['A', '-BF+AFA+FB-']; // first rule
therules[1] = ['B', '+AF-BFB-FA+']; // second rule

let whereinstring = 0; // where in the L-system are we?
p.setup = function() {
p.createCanvas(800, 800);
p.background(0);
p.stroke(255);
p.rectMode(p.CENTER);

// start the x and y position at lower-left corner
x = 0;
y = p.height-1;

// COMPUTE THE L-SYSTEM
for (let i = 0; i < numloops; i++) {
thestring = lindenmayer(thestring);
}
}

p.draw = function() {
// draw the current character in the string:
drawIt(thestring[whereinstring]);

// increment the point for where we're reading the string.
// wrap around at the end.
whereinstring++;
if (whereinstring > thestring.length-1) whereinstring = 0;
}

// interpret an L-system
function lindenmayer(s) {
let outputstring = ''; // start a blank output string
// iterate through 'therules' looking for symbol matches:
for (let i = 0; i < s.length; i++) {
let ismatch = 0; // by default, no match
for (let j = 0; j < therules.length; j++) {
if (s[i] == therules[j][0]) {
outputstring += therules[j][1]; // write substitution
ismatch = 1; // we have a match, so don't copy over symbol
break; // get outta this for() loop
}
}
// if nothing matches, just copy the symbol over.
if (ismatch == 0) outputstring+= s[i];
}
return outputstring; // send out the modified string
}

// this is a custom function that draws turtle commands
function drawIt(k) {
if (k=='F') { // draw forward
// polar to cartesian based on step and currentangle:
let x1 = x + step * p.cos(p.radians(currentangle));
let y1 = y + step * p.sin(p.radians(currentangle));
p.line(x, y, x1, y1); // connect the old and the new
// update the turtle's position:
x = x1;
y = y1;
} else if (k == '+') { //turn left
currentangle += angle;
} else if (k == '-') { //turn right
currentangle -= angle;
} else {
// pick a gaussian (D&D) distribution for the radius:
let radius = 0;
let minR = 0;
let maxR = 30;
radius += p.random(minR, maxR);
radius += p.random(minR, maxR);
radius += p.random(minR, maxR);
radius = radius / 3 * 2;
p.fill(255);
//p.rect(x, y, radius, radius);
p.ellipse(x, y, radius, radius);
}
}

}


Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more