L-systems
jsantell.com
jsantell.com
If anyone plans to test the software: I haven't run it in ages, and I suspect that the OpenGL bindings will be tricky to get working today. The rest of the code hopefully still works.
[1] https://verokster.blogspot.com/2019/03/disciples-i-ii-gl-wra...
Since you are an expert, could you share whether L-systems have any practical applications?
http://algorithmicbotany.org/papers/ has a list of papers and other related texts, including the classic book The Algorithmic Beauty of Plants.
People interested in this might also be interested in the release notes for The Grove (a Blender tree gen plugin), as they describe a number of modelled behaviours of trees in nature: phototropism, gravitropism, forking, behaviour of sapwood and heartwood, etc.: https://www.thegrove3d.com/releases/the-grove-release-8/
A recall a undergrad project where I was helping write a C wrapper around an old FORTRAN library or potential energy calculations to make them accessible in Mathematica (and yes, I am aware of how wild that sentence is). We used Mathematica to generate some potential energy surfaces (they looked like the first picture here https://sav.blogs.unr.edu/3d/ ) and for an interesting visuals I exported the models to Blender. An interesting property of these graphs is that modeling a reaction is taking a point on that graph with some amount of energy and combining it with the gradient at that point. This is essentially the same as simulating a ball rolling around within the surface. So I simulated a ball in Blender, tracked it's motion, and compared it to real life data and "actual" simulations, and found them impressively similar.
I ended up winning some aware for presenting it, it was quite a lot of fun, and now I have a publication and conversation starter of an entry on my CV.
That image shows 9 generations of the following system:
Symbols:
* Rect(Corner, Dimensions) [black]
* Room(Corner, Dimensions) [green]
* Hall(Corner, Dimensions) [blue]
Rules:
* Rect(Corner, Dimensions) => Room(Corner, Dimensions) if Dimensions matches the size of a predefined room (so I could easily place preconstructed rooms)
* Rect(Corner, Dimensions) => Hall(Corner, Dimensions) if either X or Y dimensions are 100 (1 meter width)
* Rect(Corner, Dimensions) => split at a random distance along either X or Y axis to replace with two Rects()
I'd love to see any examples that are more elegant :) One of the few posts I found was about dungeon generation[0] although I've been assured they're used all over game dev for things other than plants!
[0]: https://www.gamasutra.com/blogs/OsamaAlsalman/20180827/32531...
(Maybe they unified later?)
And even later when reimplementing the Mandelbrot algo I figured out that Fractint had a lot of tricks up its sleeve to be that fast (especially in "the lake")
1. https://www.academia.edu/38490274/Symbolic_computation_and_d...
And "Evolving Lindenmayer Systems" https://news.ycombinator.com/item?id=20588039
#lang lindenmayer, a language for L-Systems
Some of the other, older language environments I've found are the C-based CPFG, C++-based LPFG, L-Py for python
http://algorithmicbotany.org/lstudio/CPFGman.pdf http://algorithmicbotany.org/lstudio/LPFGman.pdf http://algorithmicbotany.org/papers/lpy.fps2012.pdf
The image is produced by
F: "FF",
X: "F+[[X]-FX]-F[F-FX]+X"
[0]: https://github.com/FredrikMeyer/lsystems-workshop edit index.js#L102I did one thing that goes beyond the grammars mentioned in the article and in wikipedia. You can assign an address to each leaf symbols. If you have binary rules of the form Ax->AxAx, this is easy as you are generating a binary tree and a path to that tree is just a binary number. If you are generating a programming language and each leaf node is a program statement, the return value of that statement can be assigned to that address. Then it is not difficult for each parameters in a parametric grammar to have a reference or reference offset back to these address. These address offsets can be stocastic parameters in the grammar.
To me it's more like generating a full programming language since each statement has a return value and later statements can reference these value by address, a bit like putting the value in a variable and accessing it later.
I then have a scheme to try to learn the stochastic parameters from output examples to try to produce programs that learn to generate specific output (I have had very limited success). The learning scheme includes trying to cluster together rules that generate similar subprograms.
I have a longer description here: https://www.quora.com/What-deep-learning-ideas-have-you-trie...
I expect you could get pretty far by teaching AFL (http://lcamtuf.coredump.cx/afl/) to generate inputs “through” a BNF-grammar L-system—since AFL already has the ability to explore the execution-path-space of the program-under-test.
Personally, I’m intrigued about whether L-systems can be generalized into generators for Directed Acyclic Graphs, rather than just trees. Then you could directly generate (branch-and-label-containing) machine-code, and—hooked up to a tool like AFL—fuzz processors/emulators with it.
There are already fuzzers based on this idea, for instance tavor (https://github.com/zimmski/tavor). On the purely generative side (no execution), there's blab (https://github.com/aoh/blab).
What these lack is probability parameters for each rule so that the probability distribution isn't necessarily uniform.
I guess this can't be combined with space-filling curves that form closed cycles, right? (example of such a curve: the H-curve[0])
[0] http://www.akt.tu-berlin.de/fileadmin/fg34/publications-akt/...
I've been slowing learning webgl, as soon as I have a more robust grasp of it, I'll do one 3D.
Along with Cthugha, Fractint and Form3D - this was my early PC graphics happy place.
I've been avoiding adding any JS, but interaction observers may be necessary since I haven't been happy with how any browsers handle 5 or so muted webm videos.