Anyone interested in the use of L-systems for generative art? https://github.com/decomplect/ion/blob/master/src/ion/ergo/l_system.cljc
nice, i have been playing with l systems before, will take a look at this :simple_smile:
You can use it to easily create fractal data.
nice one :simple_smile:
l-system poetry is awesome too 😄
@quentin: let me know what you think. I've worked hard on making the code as beautiful as the algorithm.
The code for the fractal I posted is in a devcard here: https://github.com/decomplect/ive/blob/master/src/ive/ergo/lindenmayer.cljs
pkobrien: at first side it look like really nice code :simple_smile: but i will take some time to read it correctly and play with it (at work here^^)
(defn dragon-sequence
"Returns a lazy sequence of vectors."
[]
(let [axiom [:F :x]
rules {:x [:x :+ :y :F :+]
:y [:- :F :x :- :y]}]
(basic-system axiom rules)))
(def dragon-render-rules {:F [:fwd 30]
:+ [:right 90 :fwd 5 :left 45 :fwd 15 :right 45 :fwd 5]
:- [:left 90 :fwd 15 :right 45 :fwd 5 :left 45 :fwd 15]
\[ [:save]
\] [:restore]
:x []
:y []})
@quentin: cool, thanks. It leverages transducers and a simple protocol for parametric systems.
@coledubs: The l-system code is completely agnostic about the words and modules that it processes, so it should be completely possible to create poetry as well, though I've not tried that.
@coledubs: have you created poetry with l-systems? Got any examples?
https://github.com/aparrish/linear-lsystem-poetry is one example
i cant find where the demo is hosted :< but instead of moving in directions its like "add a newline" or "add the next line from the poem" and so on
@coledubs: very interesting - I'll have to add that to my list of ways to render l-systems data along with turtle graphics and music.
im working on a generative sequencer thing in overtone/clojure, now im wondering if i can add lsystems to it somehow O_O
This looks like the link to the demo: http://static.decontextualize.com/lsys/
lsystems in music would be pretty cool :simple_smile:
@coledubs: seriously? That would be awesome. Overtone was on my todo list, but I've also been looking closely at Alda.
I haven't released my l-system code on clojars yet, but I think it's pretty solid and I'm now happy with how it handles parametric modules, which is basically just a simple protocol so any deftype or defrecord that implements the protocol can work.
the code im using to control drums is like [1 0.5 1 0.25 ]
and so on, so an l-system could probably generate all the probabilities for me 😄 thus saving a whole lot of typing
@coledubs: totally
and it could generate it live, or have the parameters be controlled by something else...
not just that, but I support function calls, arbitrary parametric data, and changing of rules for each generation, so you can do some really crazy stuff
here is an example, just to see how easy it is to write rules like I described:
(deftype TModule [key age]
ls/Module
(module [_] key)
Object
(toString [_] (str "<" key " " age ">")))
(defmethod clojure.core/print-method TModule [x writer]
(.write writer (str x)))
(defn type-module-example
[]
(let [axiom [(->TModule :A 0)]
rules {:A (fn [g w i m]
[(->TModule :B 0)
:-
(->TModule (.key m) (inc (.-age m)))
:-
(->TModule :B 0)])
:B (fn [g w i m]
[(->TModule :A 0)
:+
(->TModule (.key m) (inc (.-age m)))
:+
(->TModule :A 0)])}]
(ls/parametric-context-sensitive-system axiom rules)))
the g w i m
is the context-sensitive data passed to the function: generation, word, index, module
hmmm that first example you pasted made more sense to me...but i'm intrigued!
let's say you want to build into the rules that the sounds being generated get louder for each generation, you need a way to add those parameters to the module in a context-sensitive way, similar to the way I'm incrementing the age of the module
suffice it to say that after numerous attempts to allow parametric systems that are easy to define and perform well, I think the best solution is to use deftype and defrecord and a protocol. This is only needed for this most advanced form of parametric context-sensitive and (optionally) stochastic systems.
The dragon fractal I posted is just a basic system.
But if I wanted it to have some randomness, or have segments that are a different color or thickness based on its neighbor segments, or I want to fiddle with the rules for each generation so it morphs over time, there has to be a way to define those characteristics in the rules.
Similarly for music, I think there will need to be parameters to make the output something that doesn't sound overly robotic or dull.
I've got some examples here: https://github.com/decomplect/ion/blob/master/examples/ion/ergo/l_system_examples.cljc
coledubs: do you have some code online for the gen drums? :simple_smile:
https://github.com/coleww/overtone-live-coding um it is probably not in a running state currently...you kinda have to eval the files in a very specific order O_O
Think core.logic would be fun as well for generative stuff. Generating input for the Lsystems for instance
https://github.com/coleww/overtone-live-coding/blob/master/src/my_symphony/sequencer.clj this is the main thing, and /songs/blzrs.clj should be working "data" for the current version. the other songs are deprecated 😆
@meow: i'm thinking that even a simple l-system applied to a drum loop would be useful. being able to write 4 notes and have it expand to 16 or 48 beats or what have you would be really powerful, especially if I change the l-system rules on the fly too
@coledubs: I agree. I don't know Overtone, but let me know if there's anything I can do to help with the l-system. It should be very easy to start with something basic and then add complexity one little step at a time as you get comfortable with how it works.
One of the next things I'm going to do is make it easier to support cellular automata in the L-system.
i remember coding a simple turtle graphic thing in javascript, i might just write a simple script specific to my horrible notation format I have created. but im definitely interested in working with the library if you publish it
@coledubs: you could certainly use the library from github. I may publish it to clojure today or tomorrow as well.
I was holding off because I just wasn't 100% happy with the code and it has gone through some major refactoring but I think I've got it as simplified and decomplected as I can, and I think the API will be stable.
cellular automata support won't change the existing api
@coledubs: to translate the l-system sequence into your drum notation format all you need to do is some variation of mapping, like was done with the dragon fractal I posted above. Here is the code that takes the l-system dragon output and turns it into turtle commands:
(defn dragon-render-sequence
[]
(map #(into [] (comp (replace dragon-render-rules) cat) %) (dragon-sequence)))
gotta love transducers :simple_smile: