fixed and sorted/added comments to L-System
This commit is contained in:
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"liveServer.settings.port": 5501
|
||||||
|
}
|
||||||
10
liberay.html
10
liberay.html
@@ -30,7 +30,13 @@
|
|||||||
const sketches = sketchList.split(',');
|
const sketches = sketchList.split(',');
|
||||||
for (let sketch of sketches) {
|
for (let sketch of sketches) {
|
||||||
const iframe = document.createElement('iframe');
|
const iframe = document.createElement('iframe');
|
||||||
iframe.src = `loader.html?sketch=${encodeURIComponent(sketch)}`;
|
iframe.src = `loader.html?sketches=${encodeURIComponent(sketch.trim())}`;
|
||||||
|
iframe.onload = () => {
|
||||||
|
console.log(`Loaded iframe for ${sketch}`);
|
||||||
|
};
|
||||||
|
iframe.onerror = () => {
|
||||||
|
console.error(`Failed to load iframe for ${sketch}`);
|
||||||
|
};
|
||||||
// Apply size if provided
|
// Apply size if provided
|
||||||
if (sketchSize) {
|
if (sketchSize) {
|
||||||
iframe.style.width = sketchSize + 'px';
|
iframe.style.width = sketchSize + 'px';
|
||||||
@@ -41,6 +47,8 @@
|
|||||||
}
|
}
|
||||||
document.body.appendChild(iframe);
|
document.body.appendChild(iframe);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
console.error('No sketches parameter provided');
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
41
loader.html
41
loader.html
@@ -4,21 +4,37 @@
|
|||||||
<script src="js/p5.js"></script>
|
<script src="js/p5.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body style="background-color: beige; margin: 0;">
|
<body style="background-color: beige; margin: 0;">
|
||||||
<script id="sketch"></script>
|
<div id="error" style="color: red; padding: 20px; display: none;"></div>
|
||||||
<script>
|
<script>
|
||||||
const params = new URLSearchParams(window.location.search);
|
const params = new URLSearchParams(window.location.search);
|
||||||
let sketchName = "sketches/" + params.get('sketch');
|
let sketchName = params.get('sketch');
|
||||||
if (sketchName == "sketches/") {
|
if (!sketchName) {
|
||||||
sketchName = "sketches/" + params.get('sketches');
|
sketchName = params.get('sketches');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sketchName) {
|
if (sketchName) {
|
||||||
console.log(sketchName+" found");
|
|
||||||
if (!sketchName.endsWith('.js')) {
|
if (!sketchName.endsWith('.js')) {
|
||||||
sketchName += '.js';
|
sketchName += '.js';
|
||||||
}
|
}
|
||||||
|
|
||||||
const script = document.getElementById('sketch');
|
const sketchPath = 'sketches/' + sketchName;
|
||||||
script.src = sketchName;
|
console.log('Loading sketch:', sketchPath);
|
||||||
|
|
||||||
|
// Load the sketch directly
|
||||||
|
const script = document.createElement('script');
|
||||||
|
script.src = sketchPath;
|
||||||
|
script.onload = () => {
|
||||||
|
console.log('Sketch loaded successfully');
|
||||||
|
};
|
||||||
|
script.onerror = () => {
|
||||||
|
console.error('Failed to load sketch:', sketchPath);
|
||||||
|
document.getElementById('error').style.display = 'block';
|
||||||
|
document.getElementById('error').textContent = `Error loading sketch: ${sketchName}`;
|
||||||
|
};
|
||||||
|
document.head.appendChild(script);
|
||||||
|
} else {
|
||||||
|
document.getElementById('error').style.display = 'block';
|
||||||
|
document.getElementById('error').textContent = 'No sketch specified. Use ?sketch=filename.js';
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
@@ -27,5 +43,16 @@
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
#error {
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
background: white;
|
||||||
|
border: 2px solid red;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 20px;
|
||||||
|
max-width: 400px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</html>
|
</html>
|
||||||
@@ -1,178 +1,257 @@
|
|||||||
let angle = 3.141592653589*1.5;
|
/*
|
||||||
let angleDecrement = 1;
|
L-System Fractal Generator
|
||||||
let stepSize = 10;
|
|
||||||
let widthIncrement = 1;
|
The following characters have a geometric interpretation:
|
||||||
let currentWidth = 1;
|
|
||||||
let currentPosition = [501 / 2, 500];
|
Character Meaning
|
||||||
let fractalst = "FF+[+F-F-F]-[-F+F+F]";
|
F Move forward by line length drawing a line
|
||||||
let stackList = [];
|
f Move forward by line length without drawing a line
|
||||||
let lineLenghtScaleFactor = 1.5;
|
+ Turn left by turning angle
|
||||||
|
- Turn right by turning angle
|
||||||
|
| Reverse direction (ie: turn by 180 degrees)
|
||||||
|
[ Push current drawing state onto stack
|
||||||
|
] Pop current drawing state from the stack
|
||||||
|
# Increment the line width by line width increment
|
||||||
|
! Decrement the line width by line width increment
|
||||||
|
@ Draw a dot with line width radius
|
||||||
|
{ Open a polygon
|
||||||
|
} Close a polygon and fill it with fill colour
|
||||||
|
> Multiply the line length by the line length scale factor
|
||||||
|
< Divide the line length by the line length scale factor
|
||||||
|
& Swap the meaning of + and -
|
||||||
|
( Decrement turning angle by turning angle increment
|
||||||
|
) Increment turning angle by turning angle increment
|
||||||
|
*/
|
||||||
|
|
||||||
|
let angle = Math.PI * 1.5;
|
||||||
|
let turningAngle = Math.PI * 0.5;
|
||||||
|
let lineLength = 5;
|
||||||
|
let lineWidthIncrement = 1;
|
||||||
|
let currentLineWidth = 1;
|
||||||
|
let currentPosition = [0, 0];
|
||||||
|
let stateStack = [];
|
||||||
|
let lineLengthScaleFactor = 1.5;
|
||||||
let swapPlusMinusState = false;
|
let swapPlusMinusState = false;
|
||||||
let turningAngleIncrement = 0.1;
|
let turningAngleIncrement = 0.1;
|
||||||
|
let polygonVertices = [];
|
||||||
|
let polygonOpen = false;
|
||||||
|
|
||||||
//FF+[+F-F-F]-[-F+F+F] fork
|
let axiom = 'F+F+F+F';
|
||||||
|
let maxIterations = 4;
|
||||||
|
const maxCalculations = 50000;
|
||||||
|
let rules = {
|
||||||
|
'F': 'FF+F-F+F+FF'
|
||||||
|
};
|
||||||
|
|
||||||
|
// Generate the fractal string from axiom and rules
|
||||||
|
for (let i = 0; i < maxIterations; i++) {
|
||||||
|
if (axiom.length > maxCalculations) {//hard coded limit to prevent infinite loops
|
||||||
|
console.log('Reached max calculations, stopping at iteration', i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let newAxiom = '';
|
||||||
|
for (let char of axiom) {//loop through each character in the axiom and replace it with the corresponding rule
|
||||||
|
if (rules[char]) {
|
||||||
|
newAxiom += rules[char];
|
||||||
|
} else {
|
||||||
|
newAxiom += char;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
axiom = newAxiom;
|
||||||
|
}
|
||||||
|
|
||||||
function setup() {
|
function setup() {
|
||||||
console.log("setup");
|
|
||||||
createCanvas(windowWidth, windowHeight);
|
createCanvas(windowWidth, windowHeight);
|
||||||
background(255, 255, 255)
|
background(255, 255, 255);
|
||||||
noFill();
|
noFill();
|
||||||
stroke(0, 0, 0);
|
stroke(0, 0, 0);
|
||||||
strokeWeight(1);
|
strokeWeight(currentLineWidth);
|
||||||
currentPosition = [width / 2, height];
|
currentPosition = [width / 2, height - 100];
|
||||||
generateFractal();
|
generateFractal();
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateFractal() {
|
function generateFractal() {
|
||||||
for (let i = 0; i < fractalst.length; i++) {
|
for (let i = 0; i < axiom.length; i++) {
|
||||||
let c = fractalst.charAt(i);
|
let c = axiom.charAt(i);
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case "F":
|
case "F":
|
||||||
forward();
|
moveForwardDraw();
|
||||||
break;
|
|
||||||
case "+":
|
|
||||||
plus();
|
|
||||||
break;
|
|
||||||
case "-":
|
|
||||||
minus();
|
|
||||||
break;
|
break;
|
||||||
case "f":
|
case "f":
|
||||||
forwardNoLine();
|
moveForwardNoDraw();
|
||||||
|
break;
|
||||||
|
case "+":
|
||||||
|
turnLeft();
|
||||||
|
break;
|
||||||
|
case "-":
|
||||||
|
turnRight();
|
||||||
break;
|
break;
|
||||||
case "|":
|
case "|":
|
||||||
reverseDirection();
|
reverseDirection();
|
||||||
break;
|
break;
|
||||||
case "#":
|
|
||||||
lineWidthIncrement();
|
|
||||||
break;
|
|
||||||
case "!":
|
|
||||||
lineWidthDecrement();
|
|
||||||
break;
|
|
||||||
case "[":
|
case "[":
|
||||||
pushStack(i);
|
pushState(i);
|
||||||
break;
|
break;
|
||||||
case "]":
|
case "]":
|
||||||
popStack(i);
|
popState(i);
|
||||||
break;
|
break;
|
||||||
case ">":
|
case "#":
|
||||||
lineWidthMultiply();
|
incrementLineWidth();
|
||||||
break;
|
break;
|
||||||
case "<":
|
case "!":
|
||||||
lineWidthDivide();
|
decrementLineWidth();
|
||||||
break;
|
|
||||||
case "&":
|
|
||||||
swapPlusMinus();
|
|
||||||
break;
|
break;
|
||||||
case "@":
|
case "@":
|
||||||
drawDot();
|
drawDot();
|
||||||
break;
|
break;
|
||||||
|
case "{":
|
||||||
|
openPolygon();
|
||||||
|
break;
|
||||||
|
case "}":
|
||||||
|
closePolygon();
|
||||||
|
break;
|
||||||
|
case ">":
|
||||||
|
multiplyLineLength();
|
||||||
|
break;
|
||||||
|
case "<":
|
||||||
|
divideLineLength();
|
||||||
|
break;
|
||||||
|
case "&":
|
||||||
|
swapPlusMinus();
|
||||||
|
break;
|
||||||
case ")":
|
case ")":
|
||||||
angleIncrement();
|
incrementTurningAngle();
|
||||||
break;
|
break;
|
||||||
case "(":
|
case "(":
|
||||||
angleDecrement();
|
decrementTurningAngle();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
console.log("unrecognized character",c);
|
// Ignore characters not in the specification (like X)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function minus() {
|
// F: Move forward by line length drawing a line
|
||||||
|
function moveForwardDraw() {
|
||||||
|
let x = currentPosition[0] + cos(angle) * lineLength;
|
||||||
|
let y = currentPosition[1] + sin(angle) * lineLength;
|
||||||
|
if (polygonOpen) {
|
||||||
|
polygonVertices.push([x, y]);
|
||||||
|
} else {
|
||||||
|
line(currentPosition[0], currentPosition[1], x, y);
|
||||||
|
}
|
||||||
|
currentPosition = [x, y];
|
||||||
|
}
|
||||||
|
|
||||||
|
// f: Move forward by line length without drawing a line
|
||||||
|
function moveForwardNoDraw() {
|
||||||
|
let x = currentPosition[0] + cos(angle) * lineLength;
|
||||||
|
let y = currentPosition[1] + sin(angle) * lineLength;
|
||||||
|
currentPosition = [x, y];
|
||||||
|
}
|
||||||
|
|
||||||
|
// +: Turn left by turning angle
|
||||||
|
function turnLeft() {
|
||||||
if (swapPlusMinusState) {
|
if (swapPlusMinusState) {
|
||||||
angle += angleDecrement;
|
angle -= turningAngle;
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
angle -= angleDecrement;
|
angle += turningAngle;
|
||||||
}
|
}
|
||||||
|
|
||||||
function plus() {
|
// -: Turn right by turning angle
|
||||||
|
function turnRight() {
|
||||||
if (swapPlusMinusState) {
|
if (swapPlusMinusState) {
|
||||||
angle -= angleDecrement;
|
angle += turningAngle;
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
angle += angleDecrement;
|
angle -= turningAngle;
|
||||||
}
|
|
||||||
|
|
||||||
function lineWidthIncrement(){
|
|
||||||
currentWidth + widthIncrement;
|
|
||||||
strokeWeight(currentWidth);
|
|
||||||
}
|
|
||||||
|
|
||||||
function lineWidthDecrement(){
|
|
||||||
currentWidth - widthIncrement;
|
|
||||||
strokeWeight(currentWidth);
|
|
||||||
}
|
|
||||||
|
|
||||||
function forward() {
|
|
||||||
let x = currentPosition[0] + cos(angle) * stepSize;
|
|
||||||
let y = currentPosition[1] + sin(angle) * stepSize;
|
|
||||||
line(currentPosition[0], currentPosition[1], x, y);
|
|
||||||
currentPosition = [x, y];
|
|
||||||
}
|
|
||||||
|
|
||||||
function forwardNoLine(){
|
|
||||||
let x = currentPosition[0] + cos(angle) * stepSize;
|
|
||||||
let y = currentPosition[1] + sin(angle) * stepSize;
|
|
||||||
currentPosition = [x, y];
|
|
||||||
}
|
|
||||||
|
|
||||||
function backward() {
|
|
||||||
let x = currentPosition[0] - cos(angle) * stepSize;
|
|
||||||
let y = currentPosition[1] - sin(angle) * stepSize;
|
|
||||||
line(currentPosition[0], currentPosition[1], x, y);
|
|
||||||
currentPosition = [x, y];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// |: Reverse direction (turn by 180 degrees)
|
||||||
function reverseDirection() {
|
function reverseDirection() {
|
||||||
angle - 3.14159265358979323;
|
angle += Math.PI;
|
||||||
}
|
}
|
||||||
|
|
||||||
function pushStack(i){
|
// [: Push current drawing state onto stack
|
||||||
console.log(angle)
|
function pushState(i) {
|
||||||
stackList.push([i,currentPosition[0],currentPosition[1],angle,currentWidth]);
|
stateStack.push([i, currentPosition[0], currentPosition[1], angle, currentLineWidth]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function popStack(i){
|
// ]: Pop current drawing state from the stack
|
||||||
stackToPop = stackList.length - 1;
|
function popState(i) {
|
||||||
console.log(stackList[stackToPop])
|
let stackIndex = stateStack.length - 1;
|
||||||
currentPosition = [stackList[stackToPop][1],stackList[stackToPop][2]];
|
currentPosition = [stateStack[stackIndex][1], stateStack[stackIndex][2]];
|
||||||
angle = stackList[stackToPop][3];
|
angle = stateStack[stackIndex][3];
|
||||||
strokeWeight[stackList[stackToPop][4]]
|
currentLineWidth = stateStack[stackIndex][4];
|
||||||
|
strokeWeight(currentLineWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
function lineWidthMultiply(){
|
// #: Increment the line width by line width increment
|
||||||
currentWidth * lineLenghtScaleFactor;
|
function incrementLineWidth() {
|
||||||
strokeWeight(currentWidth);
|
currentLineWidth += lineWidthIncrement;
|
||||||
|
strokeWeight(currentLineWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
function lineWidthDivide(){
|
// !: Decrement the line width by line width increment
|
||||||
currentWidth / lineLenghtScaleFactor;
|
function decrementLineWidth() {
|
||||||
strokeWeight(currentWidth);
|
currentLineWidth -= lineWidthIncrement;
|
||||||
}
|
strokeWeight(currentLineWidth);
|
||||||
|
|
||||||
function swapPlusMinus(){
|
|
||||||
if (swapPlusMinusState) {
|
|
||||||
swapPlusMinusState = false;
|
|
||||||
return
|
|
||||||
}
|
|
||||||
swapPlusMinusState = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @: Draw a dot with line width radius
|
||||||
function drawDot() {
|
function drawDot() {
|
||||||
let x = currentPosition[0];
|
let x = currentPosition[0];
|
||||||
let y = currentPosition[1];
|
let y = currentPosition[1];
|
||||||
strokeWeight(currentWidth);
|
strokeWeight(currentLineWidth);
|
||||||
point(x, y);
|
point(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
function angleIncrement() {
|
// {: Open a polygon
|
||||||
angle += turningAngleIncrement;
|
function openPolygon() {
|
||||||
|
polygonVertices = [[currentPosition[0], currentPosition[1]]];
|
||||||
|
polygonOpen = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function angleDecrement() {
|
// }: Close a polygon and fill it with fill colour
|
||||||
angle -= turningAngleIncrement;
|
function closePolygon() {
|
||||||
|
if (polygonOpen && polygonVertices.length > 2) {
|
||||||
|
fill(100, 150, 255); // Default fill colour
|
||||||
|
beginShape();
|
||||||
|
for (let v of polygonVertices) {
|
||||||
|
vertex(v[0], v[1]);
|
||||||
|
}
|
||||||
|
endShape(CLOSE);
|
||||||
|
noFill(); // Reset to no fill
|
||||||
|
}
|
||||||
|
polygonVertices = [];
|
||||||
|
polygonOpen = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// >: Multiply the line length by the line length scale factor
|
||||||
|
function multiplyLineLength() {
|
||||||
|
lineLength *= lineLengthScaleFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
// <: Divide the line length by the line length scale factor
|
||||||
|
function divideLineLength() {
|
||||||
|
lineLength /= lineLengthScaleFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
// &: Swap the meaning of + and -
|
||||||
|
function swapPlusMinus() {
|
||||||
|
swapPlusMinusState = !swapPlusMinusState;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ): Increment turning angle by turning angle increment
|
||||||
|
function incrementTurningAngle() {
|
||||||
|
turningAngle += turningAngleIncrement;
|
||||||
|
}
|
||||||
|
|
||||||
|
// (: Decrement turning angle by turning angle increment
|
||||||
|
function decrementTurningAngle() {
|
||||||
|
turningAngle -= turningAngleIncrement;
|
||||||
}
|
}
|
||||||
|
|
||||||
function draw() {
|
function draw() {
|
||||||
|
|||||||
Reference in New Issue
Block a user