Steven Olmsted![]()
An l-system is a recursive parallel string rewriting system. A string value is processed iteratively. During each iteration, the string's characters are replaced with different characters based upon specific character matching rules. String manipulation of this kind isn't generally useful in and of itself but the characters in an l-system's string value are usually used to represent biological processes or fractal geometry or something interesting other than just text.
The string result of an l-system is usually used as the base of a visual rendering of some kind. This module does not provide a visual rendering component but Y.Graphics or a Canvas element can serve that purpose. gallery-cssmatrix2d can be quite helpful for implementing turtle graphics.
Y.LSystem instances have two attributes which should be set during instantiation.
axiom is the initial string value of the l-system.
rules is the set of rules used to rewrite l-system's string value.
Check the API docs for an in depth explanation of rules.
Once instantiated, the iterate method is used to update the l-system's value. Be careful not to iterate too far. The length of an l-system's value can grow exponentially so it might take quite a long time for the next iteration to complete.
The value attribute can be used to access the l-system's current value.
<script src="http://yui.yahooapis.com/3.5.1/build/yui/yui-min.js"></script>/////////////////////
// Example 1 - Sierpinski Triangle
YUI({
//Last Gallery Build of this module
gallery: 'gallery-2012.07.18-13-22'
}).use('gallery-cssmatrix2d', 'gallery-l-system', 'graphics', 'node', function (Y) {
'use strict';
var graphic = new Y.Graphic({
render: "#container"
}),
lSystem = new Y.LSystem({
axiom: 'a',
rules: {
a: 'b-a-b',
b: 'a+b+a'
}
}).iterate(8),
matrix = new Y.CSSMatrix2d().translate(21, 21),
path = graphic.addShape({
stroke: {
color: '#FFFFFF'
},
type: 'path'
}),
scale = 2;
path.moveTo(21, 21);
Y.each(lSystem.get('value').split(''), function (character) {
switch (character) {
case 'a':
case 'b':
matrix = matrix.translate(scale, 0);
path.lineTo(matrix.e, matrix.f);
break;
case '+':
matrix = matrix.rotate(60);
break;
case '-':
matrix = matrix.rotate(-60);
break;
}
});
path.end();
});
/////////////////////
// Example 2 - Heighway Dragon
YUI({
//Last Gallery Build of this module
gallery: 'gallery-2012.07.18-13-22'
}).use('gallery-cssmatrix2d', 'gallery-l-system', 'graphics', 'node', function (Y) {
'use strict';
var graphic = new Y.Graphic({
render: "#container"
}),
lSystem = new Y.LSystem({
axiom: 'fx',
rules: {
x: 'x+yf+',
y: '-fx-y'
}
}).iterate(13),
matrix = new Y.CSSMatrix2d().translate(466, 466),
path = graphic.addShape({
stroke: {
color: '#FFFFFF'
},
type: 'path'
}),
scale = 5;
path.moveTo(466, 466);
Y.each(lSystem.get('value').split(''), function (character) {
switch (character) {
case 'f':
matrix = matrix.translate(scale, 0);
path.lineTo(matrix.e, matrix.f);
break;
case '+':
matrix = matrix.rotate(90);
break;
case '-':
matrix = matrix.rotate(-90);
break;
}
});
path.end();
});
/////////////////////
// Example 3 - Pleasant Error
YUI({
//Last Gallery Build of this module
gallery: 'gallery-2012.07.18-13-22'
}).use('gallery-cssmatrix2d', 'gallery-l-system', 'graphics', 'node', function (Y) {
'use strict';
var graphic = new Y.Graphic({
render: "#container"
}),
lSystem = new Y.LSystem({
axiom: 'a-a-a-a-a',
rules: {
a: 'a-a++a+a-a-a'
}
}).iterate(4),
matrix = new Y.CSSMatrix2d().translate(233, 55),
path = graphic.addShape({
stroke: {
color: '#FFFFFF'
},
type: 'path'
}),
scale = 5;
path.moveTo(233, 55);
Y.each(lSystem.get('value').split(''), function (character) {
switch (character) {
case 'a':
matrix = matrix.translate(scale, 0);
path.lineTo(matrix.e, matrix.f);
break;
case '+':
matrix = matrix.rotate(72);
break;
case '-':
matrix = matrix.rotate(-72);
break;
}
});
path.end();
});
////////////////////
// Example 4 - Spiral Thing
YUI({
//Last Gallery Build of this module
gallery: 'gallery-2012.07.18-13-22'
}).use('gallery-cssmatrix2d', 'gallery-l-system', 'graphics', 'node', function (Y) {
'use strict';
var angle = 1,
graphic = new Y.Graphic({
render: "#container"
}),
lSystem = new Y.LSystem({
axiom: 'a',
rules: {
a: {
fn: function (match, index) {
if (!(index % 2)) {
return 'a+aa+aaa+';
}
return 'aaa';
}
},
'+': 'aaa+'
}
}).iterate(4),
matrix = new Y.CSSMatrix2d().translate(55, 55),
path = graphic.addShape({
stroke: {
color: '#FFFFFF'
},
type: 'path'
}),
scale = 5;
path.moveTo(55, 55);
Y.each(lSystem.get('value').split(''), function (character) {
switch (character) {
case 'a':
matrix = matrix.translate(scale, 0);
path.lineTo(matrix.e, matrix.f);
matrix = matrix.rotate(angle).translate(scale, 0);
path.lineTo(matrix.e, matrix.f);
matrix = matrix.rotate(angle);
break;
case '+':
angle += 1;
break;
}
});
path.end();
});
/////////////////////
// Example 5 - Random Triangle Thing
YUI({
//Last Gallery Build of this module
gallery: 'gallery-2012.07.18-13-22'
}).use('gallery-alea', 'gallery-cssmatrix2d', 'gallery-l-system', 'gallery-weighted-list', 'graphics', 'node', function (Y) {
'use strict';
var aRule = new Y.WeightedList(),
graphic = new Y.Graphic({
render: "#container"
}),
lSystem = new Y.LSystem({
axiom: 'a',
rules: {
a: aRule
}
}),
matrix = new Y.CSSMatrix2d().translate(233, 233),
path = graphic.addShape({
stroke: {
color: '#FFFFFF'
},
type: 'path'
}),
scale = 8;
aRule.add('a+a', 1);
aRule.add('a-a', 1);
aRule.add('aaa', 1);
aRule.add('aa+aa', 2);
aRule.add('aa-aa', 2);
aRule.add('aa+aaa+aa', 3);
aRule.add('aa-aaa-aa', 3);
lSystem.iterate(5);
path.moveTo(233, 233);
Y.each(lSystem.get('value').split(''), function (character) {
switch (character) {
case 'a':
matrix = matrix.translate(scale, 0);
path.lineTo(matrix.e, matrix.f);
break;
case '+':
matrix = matrix.rotate(120);
break;
case '-':
matrix = matrix.rotate(-120);
break;
}
});
path.end();
});
/////////////////////
// Example 6 - Fractal Plant
YUI({
//Last Gallery Build of this module
gallery: 'gallery-2012.07.18-13-22'
}).use('gallery-cssmatrix2d', 'gallery-l-system', 'graphics', 'node', function (Y) {
'use strict';
var graphic = new Y.Graphic({
render: "#container"
}),
lSystem = new Y.LSystem({
axiom: 'x',
rules: {
f: 'ff',
x: 'f-[[x]+x]+f[+fx]-x'
}
}).iterate(6),
matrix = new Y.CSSMatrix2d().translate(89, 377).rotate(-89),
path = graphic.addShape({
stroke: {
color: '#FFFFFF'
},
type: 'path'
}),
scale = 2,
stack = [];
path.moveTo(89, 377);
Y.each(lSystem.get('value').split(''), function (character) {
switch (character) {
case 'f':
matrix = matrix.translate(scale, 0);
path.lineTo(matrix.e, matrix.f);
break;
case '+':
matrix = matrix.rotate(21);
break;
case '-':
matrix = matrix.rotate(-21);
break;
case '[':
stack.push(matrix);
break;
case ']':
matrix = stack.pop() || matrix;
path.moveTo(matrix.e, matrix.f);
break;
}
});
path.end();
});
/////////////////////
// Example 7 - Awkwardly Animated Plant Blowing in a Storm
YUI({
//Last Gallery Build of this module
gallery: 'gallery-2012.07.18-13-22'
}).use('gallery-cssmatrix2d', 'gallery-l-system', 'graphics', 'node', function (Y) {
'use strict';
var angle = 21,
count = 20,
direction = 1,
graphic = new Y.Graphic({
render: "#container"
}),
i,
lastSwitch = 2,
lSystem = new Y.LSystem({
axiom: 'x',
rules: {
f: 'ff',
x: 'f-[[x]+x]+f[+fx]-x'
}
}).iterate(6).get('value').split(''),
matrix,
path,
paths = [],
scale = 2,
stack = [];
for (i = 0; i < count; i += 1) {
matrix = new Y.CSSMatrix2d().translate(89, 377).rotate(-89);
path = graphic.addShape({
stroke: {
color: '#FFFFFF'
},
type: 'path',
visible: false
});
path.moveTo(89, 377);
Y.each(lSystem, function (character) {
switch (character) {
case 'f':
matrix = matrix.translate(scale, 0);
path.lineTo(matrix.e, matrix.f);
break;
case '+':
matrix = matrix.rotate(angle + i / 3);
break;
case '-':
matrix = matrix.rotate(-angle + i / 3);
break;
case '[':
stack.push(matrix);
break;
case ']':
matrix = stack.pop() || matrix;
path.moveTo(matrix.e, matrix.f);
break;
}
});
path.end();
paths.push(path);
}
i = count - 1;
Y.later(100, null, function () {
paths[i].set('visible', false);
if (lastSwitch <= 0 && Math.random() >= .7) {
direction = -direction;
lastSwitch = Math.random() * count / 2;
} else {
lastSwitch -= 1;
}
i += direction;
if (i >= count || i < 0) {
direction = -direction;
i += direction;
}
paths[i].set('visible', true);
}, null, true);
});
© 2006-2013 Yahoo! Inc. All rights reserved.
All code on this site is licensed under the BSD License unless stated otherwise.
About This Site · Security Contact Info