Fork me on GitHub
#clojure-art
<
2015-09-21
>
meow13:09:34

Anyone interested in the use of L-systems for generative art? https://github.com/decomplect/ion/blob/master/src/ion/ergo/l_system.cljc

quentin13:09:58

nice, i have been playing with l systems before, will take a look at this simple_smile

meow13:09:06

You can use it to easily create fractal data.

coledubs13:09:03

l-system poetry is awesome too 😄

meow13:09:38

@quentin: let me know what you think. I've worked hard on making the code as beautiful as the algorithm.

quentin13:09:53

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^^)

meow14:09:07

(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 []})

meow14:09:01

@quentin: cool, thanks. It leverages transducers and a simple protocol for parametric systems.

meow14:09:20

@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.

meow14:09:55

@coledubs: have you created poetry with l-systems? Got any examples?

coledubs14:09:28

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

meow14:09:09

@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.

coledubs14:09:44

im working on a generative sequencer thing in overtone/clojure, now im wondering if i can add lsystems to it somehow O_O

meow14:09:54

This looks like the link to the demo: http://static.decontextualize.com/lsys/

quentin14:09:28

lsystems in music would be pretty cool simple_smile

meow14:09:34

@coledubs: seriously? That would be awesome. Overtone was on my todo list, but I've also been looking closely at Alda.

meow14:09:40

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.

coledubs14:09:41

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

coledubs14:09:44

and it could generate it live, or have the parameters be controlled by something else...

meow14:09:47

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

meow14:09:32

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)))

meow14:09:56

the g w i m is the context-sensitive data passed to the function: generation, word, index, module

coledubs14:09:33

hmmm that first example you pasted made more sense to me...but i'm intrigued!

meow14:09:07

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

meow14:09:13

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.

meow14:09:10

The dragon fractal I posted is just a basic system.

meow14:09:28

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.

meow14:09:29

Similarly for music, I think there will need to be parameters to make the output something that doesn't sound overly robotic or dull.

jellea14:09:50

coledubs: do you have some code online for the gen drums? simple_smile

coledubs14:09:44

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

jellea14:09:47

Think core.logic would be fun as well for generative stuff. Generating input for the Lsystems for instance

coledubs14:09:39

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 😆

coledubs14:09:20

@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

meow14:09:31

@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.

meow14:09:32

One of the next things I'm going to do is make it easier to support cellular automata in the L-system.

coledubs14:09:47

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

meow14:09:00

@coledubs: you could certainly use the library from github. I may publish it to clojure today or tomorrow as well.

meow14:09:05

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.

meow14:09:50

cellular automata support won't change the existing api

meow14:09:55

@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)))

meow14:09:36

gotta love transducers simple_smile