| 
									
										
										
										
											2024-10-29 21:40:31 -04:00
										 |  |  | // L-System KCL | 
					
						
							|  |  |  | // Zoo Corporation ⓒ 2024 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Comparators | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-01 11:36:51 -05:00
										 |  |  | fn cond(@bools) { | 
					
						
							| 
									
										
										
										
											2025-04-30 13:12:40 +12:00
										 |  |  |   return fn(a, b) { | 
					
						
							| 
									
										
										
										
											2025-04-30 11:07:05 -04:00
										 |  |  |     x = min([max([-1, a-b]), 1]) + 1 | 
					
						
							| 
									
										
										
										
											2024-10-29 21:40:31 -04:00
										 |  |  |     return bools[x] | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-01 11:36:51 -05:00
										 |  |  | fn Not(@b) { return if b { false } else { true } } | 
					
						
							| 
									
										
										
										
											2025-04-30 13:12:40 +12:00
										 |  |  | fn And(a, b) { return if a { if b { true } else { false } } else { false }} | 
					
						
							|  |  |  | fn Or(a, b) { return if a { true } else { if b { true } else { false }}} | 
					
						
							| 
									
										
										
										
											2024-10-29 21:40:31 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | Eq = cond([false, true, false]) | 
					
						
							|  |  |  | Lt = cond([true, false, false]) | 
					
						
							|  |  |  | Gt = cond([false, false, true]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-01 11:36:51 -05:00
										 |  |  | fn Lte(a, b) { return Not(Gt(a = a, b = b)) } | 
					
						
							|  |  |  | fn Gte(a, b) { return Not(Lt(a = a, b = b)) } | 
					
						
							| 
									
										
										
										
											2024-10-29 21:40:31 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-01 16:32:46 -08:00
										 |  |  | // L-system | 
					
						
							| 
									
										
										
										
											2024-10-29 21:40:31 -04:00
										 |  |  | // Note: it was most concise to encode productions directly in axioms. | 
					
						
							|  |  |  | // Change them as you need. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-01 11:36:51 -05:00
										 |  |  | fn setSketch(@state, q) { | 
					
						
							| 
									
										
										
										
											2024-10-29 21:40:31 -04:00
										 |  |  |   return { | 
					
						
							| 
									
										
										
										
											2025-04-30 13:12:40 +12:00
										 |  |  |     depthMax = state.depthMax, | 
					
						
							|  |  |  |     depth = state.depth + 1, | 
					
						
							|  |  |  |     currentLength = state.currentLength, | 
					
						
							|  |  |  |     factor = state.factor, | 
					
						
							|  |  |  |     currentAngle = state.currentAngle, | 
					
						
							|  |  |  |     angle = state.angle, | 
					
						
							| 
									
										
										
										
											2024-12-17 09:01:51 +13:00
										 |  |  |     q | 
					
						
							| 
									
										
										
										
											2024-10-29 21:40:31 -04:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-01 11:36:51 -05:00
										 |  |  | fn setDepth(@state, q) { | 
					
						
							| 
									
										
										
										
											2024-10-29 21:40:31 -04:00
										 |  |  |   return { | 
					
						
							| 
									
										
										
										
											2025-04-30 13:12:40 +12:00
										 |  |  |     depthMax = state.depthMax, | 
					
						
							|  |  |  |     depth = q, | 
					
						
							|  |  |  |     currentLength = state.currentLength, | 
					
						
							|  |  |  |     factor = state.factor, | 
					
						
							|  |  |  |     currentAngle = state.currentAngle, | 
					
						
							|  |  |  |     angle = state.angle, | 
					
						
							|  |  |  |     q = state.q | 
					
						
							| 
									
										
										
										
											2024-10-29 21:40:31 -04:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-01 11:36:51 -05:00
										 |  |  | fn setAngle(@state, q) { | 
					
						
							| 
									
										
										
										
											2024-10-29 21:40:31 -04:00
										 |  |  |   return { | 
					
						
							| 
									
										
										
										
											2025-04-30 13:12:40 +12:00
										 |  |  |     depthMax = state.depthMax, | 
					
						
							|  |  |  |     depth = state.depth, | 
					
						
							|  |  |  |     currentLength = state.currentLength, | 
					
						
							|  |  |  |     factor = state.factor, | 
					
						
							|  |  |  |     currentAngle = q, | 
					
						
							|  |  |  |     angle = state.angle, | 
					
						
							|  |  |  |     q = state.q | 
					
						
							| 
									
										
										
										
											2024-10-29 21:40:31 -04:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-01 11:36:51 -05:00
										 |  |  | fn setLength(@state, q) { | 
					
						
							| 
									
										
										
										
											2024-10-29 21:40:31 -04:00
										 |  |  |   return { | 
					
						
							| 
									
										
										
										
											2025-04-30 13:12:40 +12:00
										 |  |  |     depthMax = state.depthMax, | 
					
						
							|  |  |  |     depth = state.depth, | 
					
						
							|  |  |  |     currentLength = q, | 
					
						
							|  |  |  |     factor = state.factor, | 
					
						
							|  |  |  |     currentAngle = state.currentAngle, | 
					
						
							|  |  |  |     angle = state.angle, | 
					
						
							|  |  |  |     q = state.q | 
					
						
							| 
									
										
										
										
											2024-10-29 21:40:31 -04:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-01 11:36:51 -05:00
										 |  |  | fn Gt2(@state) { return setLength(state, q = state.currentLength * state.factor) } | 
					
						
							|  |  |  | fn Lt2(@state) { return setLength(state, q = state.currentLength / state.factor) } | 
					
						
							|  |  |  | fn Add(@state) { return setAngle(state, q = rem(state.currentAngle - state.angle, divisor = 360)) } | 
					
						
							|  |  |  | fn Sub(@state) { return setAngle(state, q = rem(state.currentAngle + state.angle, divisor = 360)) } | 
					
						
							| 
									
										
										
										
											2024-10-29 21:40:31 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Only necessary to get around recursion limitations... | 
					
						
							| 
									
										
										
										
											2025-05-01 11:36:51 -05:00
										 |  |  | fn F(@state, F) { | 
					
						
							|  |  |  |   return if Lt(a = state.depth, b = state.depthMax) { | 
					
						
							|  |  |  |     stateNext = state |> setDepth(%, q = state.depth + 1) | 
					
						
							| 
									
										
										
										
											2024-10-29 21:40:31 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Produce | 
					
						
							|  |  |  |     // Note:if you need [ and ], just save state to a variable. | 
					
						
							|  |  |  |     stateNext | 
					
						
							| 
									
										
										
										
											2025-05-01 11:36:51 -05:00
										 |  |  |       |> F(%, F = F) |> Sub(%) |> F(%, F = F) | 
					
						
							| 
									
										
										
										
											2024-10-29 21:40:31 -04:00
										 |  |  |       |> Add(%) |> Add(%) | 
					
						
							| 
									
										
										
										
											2025-05-01 11:36:51 -05:00
										 |  |  |       |> F(%, F = F) |> Sub(%) |> F(%, F = F) | 
					
						
							|  |  |  |       |> setDepth(%, q = stateNext.depth - 1) | 
					
						
							| 
									
										
										
										
											2024-10-29 21:40:31 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     // Pass onto the next instruction | 
					
						
							| 
									
										
										
										
											2025-05-01 11:36:51 -05:00
										 |  |  |     state |> setSketch(%, q = angledLine(state.q, angle = state.currentAngle, length = state.currentLength)) | 
					
						
							| 
									
										
										
										
											2024-10-29 21:40:31 -04:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-01 11:36:51 -05:00
										 |  |  | fn LSystem(@args, axioms) { | 
					
						
							| 
									
										
										
										
											2025-03-01 16:32:46 -08:00
										 |  |  |     myThing = startSketchOn(XY) | 
					
						
							| 
									
										
										
										
											2025-04-25 16:01:35 -05:00
										 |  |  |     |> startProfile(at = [0, 0]) | 
					
						
							| 
									
										
										
										
											2024-10-29 21:40:31 -04:00
										 |  |  |   return axioms({ | 
					
						
							| 
									
										
										
										
											2025-04-30 13:12:40 +12:00
										 |  |  |     depthMax = args.iterations, | 
					
						
							|  |  |  |     depth = 0, | 
					
						
							|  |  |  |     currentLength = 1.0, | 
					
						
							|  |  |  |     factor = args.factor, | 
					
						
							|  |  |  |     currentAngle = 0, | 
					
						
							|  |  |  |     angle = args.angle, | 
					
						
							| 
									
										
										
										
											2025-03-01 16:32:46 -08:00
										 |  |  |     q = myThing, | 
					
						
							| 
									
										
										
										
											2024-10-29 21:40:31 -04:00
										 |  |  |   }) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | LSystem({ | 
					
						
							| 
									
										
										
										
											2025-04-30 13:12:40 +12:00
										 |  |  |   iterations = 1, | 
					
						
							|  |  |  |   factor = 1.36, | 
					
						
							|  |  |  |   angle = 60, | 
					
						
							| 
									
										
										
										
											2025-05-01 11:36:51 -05:00
										 |  |  | }, axioms = fn(@q) { | 
					
						
							|  |  |  |   result = q |> F(%, F = F) |> Add(%) |> Add(%) |> F(%, F = F) |> Add(%) |> Add(%) |> F(%, F = F) | 
					
						
							| 
									
										
										
										
											2024-12-17 09:01:51 +13:00
										 |  |  |   return result.q | 
					
						
							| 
									
										
										
										
											2024-10-29 21:40:31 -04:00
										 |  |  | }) | 
					
						
							| 
									
										
										
										
											2025-05-01 11:36:51 -05:00
										 |  |  | 
 |