Skip to content

Instantly share code, notes, and snippets.

@patilswapnilv
Created June 30, 2015 06:53
Show Gist options
  • Save patilswapnilv/afc8b4f1fad56f0ebff8 to your computer and use it in GitHub Desktop.
Save patilswapnilv/afc8b4f1fad56f0ebff8 to your computer and use it in GitHub Desktop.
Spiral L-system
<div id="result" class="center"></div>
<canvas id="canvas" class="center"></canvas>
<input id="iterationsSlider" type="range" min="0" max="100" step="1" value="30">
/*
"Invented" by me, Johan Karlsson
Spiral drawn by an L-system
Axiom: FmAFmFpFB
Rules: (A→FMA), (B→PFB)
F: draw forward
m: turn left
M: turn left, decrease step size
p: turn right
P: turn right, increase step size
Angle: 90deg
Side note:
* m and M for minus
* p and P for plus
*/
(function(spiral) {
// Private members
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var colorBit = false;
var stepFactor = 12;
var lineWidth = 4;
var x;
var y;
// Axiom
var axiom = "FmAFmFpFB";
// Production
function produce(iterations) {
var result = axiom;
for(var i = 0; i < iterations; i++) {
// Rules
result = result.replace("A", "FMA");
result = result.replace("B", "PFB");
}
return result;
}
function getDirection (direction) {
if(direction === -1) {
return 3;
} else if(direction === 4) {
return 0;
} else {
return direction;
}
}
function drawStep(direction, stepLength) {
ctx.strokeStyle = colorBit ? "purple" : "rebeccapurple";
ctx.beginPath();
ctx.moveTo(x, y);
switch(direction) {
case 0:
x += stepLength * stepFactor;
break;
case 1:
y += stepLength * stepFactor;
break;
case 2:
x -= stepLength * stepFactor;
break;
case 3:
y -= stepLength * stepFactor;
break;
}
ctx.lineTo(x, y);
ctx.stroke();
colorBit = !colorBit;
}
// Public members
spiral.draw = function (iterations) {
var direction = 0;
var stepLength = iterations + 1;
canvas.width = stepLength * stepFactor + lineWidth;
canvas.height = stepLength * stepFactor + lineWidth;
ctx.lineWidth = lineWidth;
ctx.lineCap = "square";
x = 0 + lineWidth/2;
y = canvas.height - lineWidth/2;
var result = produce(iterations);
for(var stringIndex = 0; stringIndex < result.length; stringIndex++) {
switch(result[stringIndex]) {
case "F":
drawStep(direction, stepLength);
break;
case "M":
stepLength--;
// Intentional fall through
case "m":
direction = getDirection(direction - 1);
break;
case "P":
stepLength++;
// Intentional fall through
case "p":
direction = getDirection(direction + 1);
break;
}
}
return result;
}
})(window.spiral = window.spiral || {});
var resultDiv = document.getElementById("result");
var result = spiral.draw(20);
resultDiv.innerHTML = result;
document.getElementById("iterationsSlider").addEventListener("change", function () {
result = spiral.draw(parseInt(this.value));
resultDiv.innerHTML = result;
});
html {
margin: 0;
height: 100%;
background-color: #0F0F0F;
}
#iterationsSlider {
position: absolute;
margin: 3vmin;
}
.center {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
#result {
font-family: monospace;
font-size: xx-large;
ddisplay: inline-block;
color: #121212;
hheight: 100%;
width: 50%;
word-wrap: break-word;
}
@media (max-width: 600px) {
#iterationsSlider {
display: none;
}
}
@patilswapnilv
Copy link
Author

👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment