You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

183 lines
4.1 KiB

function rule_applicable(word, pos, consumed, rule) {
for(let i=0; i<rule.length; i++) {
if((word[pos+i] != rule[i]) | (consumed[pos+i] == true)) {
return false;
}
}
return true;
}
function generate(start, rules, iterations) {
if(iterations == 0) {
return start;
}
var word = start;
var consumed = new Array(word.length);
for(let rule of rules) {
let pos = 0;
var newword = [];
var newconsumed = [];
while(pos < word.length) {
if(rule_applicable(word, pos, consumed, rule[0])) {
var ruleres;
if(typeof rule[1] == 'function') {
ruleres = rule[1]();
} else {
ruleres = rule[1];
}
newword += ruleres;
for(let i=0; i<ruleres.length; i++) {
newconsumed.push(true);
}
pos += rule[0].length;
} else {
newword += word[pos];
newconsumed.push(false);
pos += 1;
}
}
word = newword;
consumed = newconsumed;
}
return generate(newword, rules, iterations - 1);
}
function draw_initstate(p, state) {
if(!('dir' in state)) {
state.dir = 0;
state.turnnoise = 0;
state.lennoise = 0;
}
if(!('stepsize' in state)) {
state.stepsize = 1;
}
if(!('curpath' in state)) {
p.addChild(new paper.Path());
state.curpath = p.lastChild;
}
}
function draw_set_dir(dir) {
return function(p, state) {
state.dir = dir;
}
}
function draw_set_turn_noise(level) {
return function(p, state) {
state.turnnoise = level;
}
}
function draw_set_length_noise(level) {
return function(p, state) {
state.lennoise = level;
}
}
function draw_forward(factor=1) {
return function(p, state) {
draw_initstate(p, state);
if(state.curpath.segments.length == 0) {
state.curpath.add(new paper.Point(0, 0));
console.log('---------------------------');
}
var lastp = state.curpath.segments[state.curpath.segments.length - 1].point;
var noise = 1 + (Math.random() - 0.5) * state.lennoise;
state.curpath.add(lastp.add(new paper.Point(
Math.sin(state.dir) * state.stepsize * factor * noise,
Math.cos(state.dir) * state.stepsize * factor * noise
)));
}
}
function draw_stepsize_mul(factor) {
return function(p, state) {
if(typeof factor == 'function') {
var f = factor();
} else {
var f = factor;
}
draw_initstate(p, state);
state.stepsize *= f;
};
}
function draw_turn(angle) {
return function(p, state) {
draw_initstate(p, state);
state.dir += angle;
}
}
function draw_angle_turn(fac) {
return function(p, state) {
draw_initstate(p, state);
var a = state.angle * (1 + (Math.random() - 0.5) * state.turnnoise);
state.dir += a * fac;
}
}
function draw_angle_init(angle) {
return function(p, state) {
state.angle = angle;
}
}
function draw_angle_add(delta) {
return function(p, state) {
state.angle += delta;
}
}
function draw_state_push() {
return function(p, state) {
if(typeof state.stack == 'undefined') {
state.stack = new Array();
}
state.stack.push({
pos: state.curpath.segments[state.curpath.segments.length - 1].point,
dir: state.dir,
stepsize: state.stepsize,
});
}
}
function draw_state_pop() {
return function(p, state) {
var s = state.stack.pop();
state.dir = s.dir;
state.stepsize = s.stepsize;
p.addChild(new paper.Path());
state.curpath = p.lastChild;
state.curpath.add(s.pos);
}
}
function draw(word, actions) {
var p = new paper.CompoundPath();
var state = {};
for(let w of word) {
if(w in actions) {
actions[w](p, state);
}
}
return p;
}