1

I need help figuring out how to add start and rules to the code. I'd like to be able to specify rules and type in a start function into the menu. I'm a math student and not really versed in js, but any help is appreciated!

Here's the code:

https://codepen.io/odedw/pen/RwVyaR

Thanks so much in advance for anyone who helps!

(function(){     
//input
var input = {
    angle: 25,
    segmentLength:  5,
    iterations:  6,
    scale: 1,
    redraw:function(){
        shouldStop = true;   
        setTimeout(init,50);
    },
    lSystem: {
        start: 'X',
        rules: {
            'F': 'FF',
            'X': 'F-[[X]+X]+F[+FX]-X'            
        }
    }
};

var color = '#fff',
    angleInRadians,
    canvas,
    context,
    expression,
    currentInstructionIndex = 0,
    currentPosition = {x: 0, y: 0, angle: Math.PI/2},
    positionStack = [],
    shouldStop;

function computeExpression(system, n) {
    var result = '';
    var exp = system.start;
    for (var i=0; i<n; i++){
        for (var j=0; j<exp.length; j++){
            var c = exp[j];
            result += system.rules[c] ? system.rules[c] : c;
        }
        exp = result;
        result = '';
    }        
    return exp;


}

function initCanvas(){
    canvas = document.getElementsByTagName('canvas')[0];
    canvas.width  = canvas.offsetWidth;
    canvas.height = canvas.offsetHeight;        
    context = canvas.getContext("2d");
    context.strokeStyle = color;
    context.lineWidth = 1;
}

function start(){
    currentInstructionIndex = 0;
    shouldStop = false;
    
    context.clearRect(0, 0, canvas.width, canvas.height);
    context.scale(input.scale, input.scale);
    currentPosition.x = 0;
    currentPosition.y = context.canvas.height / (2 * input.scale);
    currentPosition.angle = Math.PI/2;
    context.beginPath();

    drawExpression();
}

function drawExpression(){
    if (shouldStop) {
        return;    
    }
    var inst = expression[currentInstructionIndex];
    var shouldRequestFrame = processInstruction(inst);
    currentInstructionIndex++;
    if (shouldRequestFrame){
        requestAnimationFrame(drawExpression);
    }
    else {
        drawExpression();
    }

}

function processInstruction(instruction){        
    angleInRadians =  input.angle * Math.PI / 180;
    switch(instruction){
        case 'F':
            context.moveTo(currentPosition.x, currentPosition.y);
            currentPosition.x = currentPosition.x + Math.sin(currentPosition.angle) * input.segmentLength;
            currentPosition.y = currentPosition.y + Math.cos(currentPosition.angle) * input.segmentLength;
            context.lineTo(currentPosition.x, currentPosition.y);
            context.stroke();
            return true;
        case '+':
            currentPosition.angle += angleInRadians;
            break;
        case '-':
            currentPosition.angle -= angleInRadians;
            break;
        case '[':
            positionStack.push({x: currentPosition.x, y: currentPosition.y, angle: currentPosition.angle});
            break;
        case ']':
            currentPosition = positionStack.pop();
            break;                
    }
    return false;

}

function init(){               
    expression = computeExpression(input.lSystem, input.iterations);
    initCanvas();
    start();
}

document.addEventListener("DOMContentLoaded", function() {
    var gui = new dat.GUI();
    gui.add(input, 'angle',15,90).step(1);
    gui.add(input, 'segmentLength', 5, 30).step(1);
    gui.add(input, 'iterations', 1, 9).step(1);
    gui.add(input, 'redraw');
    init();
});

}());

Operator
  • 19
  • 1

0 Answers0