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.
142 lines
3.0 KiB
142 lines
3.0 KiB
|
|
function startswith(a, b) { |
|
for(let i=0; i<b.length; i++) { |
|
// in JS, ['X'] == 'X' |
|
if((a[i] != b[i]) | (typeof a[i] != typeof b[i])) { |
|
return false; |
|
} |
|
} |
|
return true; |
|
} |
|
|
|
|
|
function generate(start, rules, iterations) { |
|
if(iterations == 0) { |
|
return start; |
|
} |
|
|
|
for(let rule of rules) { |
|
let pos = 0; |
|
while(pos < start.length) { |
|
let w = start.slice(pos, pos + rule[0].length); |
|
if(startswith(w, rule[0])) { |
|
start.splice(pos, rule[0].length, rule[1]) |
|
pos += rule[0].length; |
|
} else { |
|
pos += 1; |
|
} |
|
} |
|
} |
|
|
|
// TODO find a better way |
|
let ret = []; |
|
for(let x of start) { |
|
if(typeof x === 'object') { |
|
// TODO why? |
|
//ret.concat(x); |
|
ret = ret.concat(x); |
|
} else { |
|
ret.push(x); |
|
} |
|
} |
|
return generate(ret, rules, iterations - 1); |
|
} |
|
|
|
|
|
function draw_initstate(p, state) { |
|
if(!('dir' in state)) { |
|
state.dir = 0; |
|
} |
|
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_forward() { |
|
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; |
|
state.curpath.add(lastp.add( |
|
new paper.Point(Math.sin(state.dir), Math.cos(state.dir)) |
|
)); |
|
} |
|
} |
|
|
|
|
|
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); |
|
state.dir += state.angle * 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, |
|
}); |
|
} |
|
} |
|
|
|
|
|
function draw_state_pop() { |
|
return function(p, state) { |
|
var s = state.stack.pop(); |
|
state.dir = s.dir; |
|
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; |
|
}
|
|
|