tmhglnd / total-serialism

Toolbox full of Algorithmic Composition methods
MIT License
151 stars 11 forks source link

added L system function #1

Closed rexmalebka closed 4 years ago

rexmalebka commented 4 years ago

Added L System function

it could be used with:

> t.Algorithmic.linden('A', {'A':'B','B':'AB'},3)
'BAB'
> t.Algorithmic.linden('A', {'A':'B','B':'AB'},5)
'BABABBAB'

as it concerns, it works only with character rules only and only for strings, if we would like to use multiple character keys we need to use regex.

for example:

> t.Algorithmic.linden('A', {'A':'B','B':'AB','AB':'X'},5)
'BABABBAB'

this won't work for AB : 'X' rule

Also I was thinking if this could return a generator so people could yield values whenever they want, removing recursion things, I don't know if this should be kept as simple as possible.

tmhglnd commented 4 years ago

Nice suggestion, this was also on my list for sure. Will have a look at it soon!

tmhglnd commented 4 years ago

I merged it, but did make a few adjustments that I think fit the entire library a bit better.

  1. When the axiom is an integer it will return an array instead of a string
  2. The default ruleset is A>AB B>A, but expressed as integers 1>01 and 0>1, so this can immediately be used as a generator for a rhythm (similar euclid() and hexBeat()).
  3. The number of generations is the second argument, so it is still possible to generate a result without specifying the production rules.

Normal string expansion:

// Koch curve
Algo.linden('F', 2, {F: 'F+F-F-F+F'});
//=> 'F+F-F-F+F+F+F-F-F+F-F+F-F-F+F-F+F-F-F+F+F+F-F-F+F'

// Cantor set
Algo.linden('A', 3, {A: 'ABA', B: 'BBB'});
//=> 'ABABBBABABBBBBBBBBABABBBABA'

// Sierpinski Triangle
Algo.linden('F-G-G', 1, {'F': 'F−G+F+G−F', 'G' : 'GG'});
//=> 'F−G+F+G−F-GG-GG'

L-System with integers and arrays

Algo.linden();
//default => [1, 0, 1, 1, 0]

// Cantor set as 0's and 1's in an array ruleset
Algo.linden(1, 3, {1: [1, 0, 1], 0: [0, 0, 0]});
//=> [1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1]

// Set more complex rules for generating semitones for example
var complexRules = {
    0: [0, 3, 7],
    3: [-1, 0],
    7: [12, 19, 0],
    12: [12, 0, 0, 5], 
    5: [0, -3, 0]
}

Algo.linden(0, 2, complexRules);
//=> [0, 3, 7, -1, 0, 12, 19, 0, -1, 0, 3, 7, 12, 0, 0, 5, 19, 0, 3, 7]