use canvasfx, math, functional // https://github.com/SeTSeR/KochSnowflake width = 675 height = 500 context = window("Koch Snowflake", width, height) GO = 0 TURN = 1 def Fractal(startStep = 0) { result = {} result.fract = startStep ? [[GO, startStep]] : [] result.next = def(fract) { fractal = Fractal() def translate(input) = input[0] == GO ? [input[0], input[1] / 3] : input fractlist = map(fract, ::translate) fractal.fract = fractlist fractal.fract ::= [TURN, -PI / 3] fractal.fract <<= fractlist fractal.fract ::= [TURN, 2*PI / 3] fractal.fract <<= fractlist fractal.fract ::= [TURN, -PI / 3] fractal.fract <<= fractlist return fractal } result.toDraw = def(fract) { res = Fractal() res.fract = fract res.fract ::= [TURN, 2*PI / 3] res.fract <<= fract res.fract ::= [TURN, 2*PI / 3] res.fract <<= fract return res } return result } def draw(fractal) { x = 200 y = height - 100 / sqrt(3) angle = -PI / 2 context.setFill(Color.BLACK) context.fillRect(0, 0, width, height) context.setStroke(Color.GREEN) context.beginPath() context.moveTo(x, y) for action : fractal.fract { match action[0] { case GO: { x += action[1] * cos(angle) y += action[1] * sin(angle) context.lineTo(x, y) } case TURN: angle += action[1] } } context.closePath() context.stroke() } fractal = Fractal(400.0) draw(fractal.toDraw(fractal.fract)) addEventHandler(Events.KEY_PRESSED, def(e) { if (e.code == KeyCode.SPACE) { fractal = fractal.next(fractal.fract) draw(fractal.toDraw(fractal.fract)) } })