Open
Description
// L-System KCL
// Zoo Corporation ⓒ 2024
// L-system
// Note: it was most concise to encode productions directly in axioms.
// Change them as you need.
deg = pi()*2 / 360
fn setSketch = (state, _) => {
return {
depthMax: state.depthMax,
depth: state.depth + 1,
currentLength: state.currentLength,
factor: state.factor,
currentAngle: state.currentAngle,
angle: state.angle,
_: _
}
}
fn setDepth = (state, _) => {
return {
depthMax: state.depthMax,
depth: _,
currentLength: state.currentLength,
factor: state.factor,
currentAngle: state.currentAngle,
angle: state.angle,
_: state._
}
}
fn setAngle = (state, _) => {
return {
depthMax: state.depthMax,
depth: state.depth,
currentLength: state.currentLength,
factor: state.factor,
currentAngle: _,
angle: state.angle,
_: state._
}
}
fn setLength = (state, _) => {
return {
depthMax: state.depthMax,
depth: state.depth,
currentLength: _,
factor: state.factor,
currentAngle: state.currentAngle,
angle: state.angle,
_: state._
}
}
fn Gt2 = (state) => { return setLength(state, state.currentLength * state.factor) }
fn Lt2 = (state) => { return setLength(state, state.currentLength / state.factor) }
fn Add = (state) => { return setAngle(state, rem(int(state.currentAngle - state.angle), 360)) }
fn Sub = (state) => { return setAngle(state, rem(int(state.currentAngle + state.angle), 360)) }
// Only necessary to get around recursion limitations...
fn X = (state, X) => {
return if state.depth < state.depthMax {
stateNext = state |> setDepth(%, state.depth + 1)
// Produce
// Note:if you need [ and ], just save state to a variable.
stateNext
|> F(%, F) |> Sub(%) |> F(%, F)
|> Add(%) |> Add(%)
|> F(%, F) |> Sub(%) |> F(%, F)
|> setDepth(%, stateNext.depth - 1)
} else {
// Pass onto the next instruction
state |> setSketch(%, angledLine({ angle: state.currentAngle, length: state.currentLength }, state._))
}
}
// Only necessary to get around recursion limitations...
fn F = (state, F) => {
// Pass onto the next instruction
state |> setSketch(%, angledLine({ angle: state.currentAngle, length: state.currentLength }, state._))
}
fn LSystem = (args, axioms) => {
return axioms({
depthMax: args.iterations,
depth: 0,
currentLength: 1.0,
factor: args.factor,
currentAngle: 0,
angle: args.angle,
_: startSketchAt([0, 0]),
})
}
LSystem({
iterations: 2,
factor: 1.36,
angle: 60,
}, (_) => {
result = _ |> F(%, F) |> Add(%) |> Add(%) |> F(%, F) |> Add(%) |> Add(%) |> F(%, F)
return result._
})