Library for working with L-systems. You can read more here.
public static void Main(string[] args)
{
var A = new UniversalModule("A"); // first module A
var B = new UniversalModule("B"); // second module B
var rule1 = new UniversalRule(A, new []{A, B}); // rule A -> AB
var rule2 = new UniversalRule(B, new []{A}); //rule B -> A
var lSys = new BasicLSystem<UniversalModule, UniversalRule>(new []{B}, new []{A, B}, new []{rule1, rule2}); // l-system creation
lSys.Init();
Display(lSys.CurrentState); // display axiome
for (var i = 0; i < 5; i++)
{
// make substitution and display
lSys.Step();
Display(lSys.CurrentState);
}
}
private static void Display(IEnumerable<IModule> state)
{
foreach (var m in state)
{
Console.Write($"{m.Id}; ");
}
Console.WriteLine();
}
//B;
//A;
//A; B;
//A; B; A;
//A; B; A; A; B;
//A; B; A; A; B; A; B; A;
supports any kind of parameters
public static void Main(string[] args)
{
var numberParameter = new BasicParameter<int>(1, "num"); // declare int parameter "num" with initial value 1
var A = new UniversalModule("A", new[] { numberParameter }); // assign parameter "num" to module A
var B = new UniversalModule("B");
//create parameter transformation. It is used to change parameters in substitution. This particular one changes only one parameter
var parameterTransformation = new ParameterTransformation<int>("num", (v) => v + 1); // it finds int value of parameter "num" of predecessor and assigns
// value + 1 to parameter "num" of first successor;
var rule1 = new UniversalRule(A, new []{A, B}, new[] { parameterTransformation }); // assign parameter transformation to substitution rule
var rule2 = new UniversalRule(B, new []{A}); // this rule does not have any parameter transformations but A has a parameter "num". It's value
// will be set to 1 as it is initial value of "num" parameter.
var lSys = new BasicLSystem<UniversalModule, UniversalRule>(new []{B}, new []{A, B}, new []{rule1, rule2});
lSys.Init();
Display(lSys.CurrentState);
for (var i = 0; i < 5; i++)
{
lSys.Step();
Display(lSys.CurrentState);
}
}
private static void Display(IEnumerable<IModule> state)
{
foreach (var m in state)
{
if (m.parameters.Count() == 0)
Console.Write($"{m.Id}; ");
else
{
Console.Write($"{m.Id}({string.Join(", ", m.parameters)}); ");
}
}
Console.WriteLine();
}
//B;
//A(num=1);
//A(num=2); B;
//A(num=3); B; A(num=1);
//A(num=4); B; A(num=1); A(num=2); B;
//A(num=5); B; A(num=1); A(num=2); B; A(num=3); B; A(num=1);
Also lib allows defining L-system with xml document. For example following file (located at relative path l-system.xml
) defines L-system presented above
<?xml version="1.0"?>
<lsml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="LSystem https://raw.githubusercontent.com/hevezolly/LSystem/master/XmlLSystem/LSML.xsd"
xmlns="LSystem">
<declaration>
<parameters>
<parameter type="int" param_id="num">1</parameter>
</parameters>
<modules>
<module id="A">
<parameter param_id="num"/>
</module>
<module id="B"></module>
</modules>
<axiome>
<module id="B"/>
</axiome>
</declaration>
<rule source="A">
<successor id="A">
<parameterUpdate param_id="num">source.num + 1</parameterUpdate>
</successor>
<successor id="B"></successor>
</rule>
<rule source="B">
<successor id="A"></successor>
</rule>
</lsml>
It can be accessed by following method
public static void Main(string[] args)
{
var lSys = new XmlLSystemProvider().Load("l-system.xml").Compile();
lSys.Init();
Display(lSys.CurrentState);
for (var i = 0; i < 5; i++)
{
lSys.Step();
Display(lSys.CurrentState);
}
}
private static void Display(IEnumerable<IModule> state)
{
foreach (var m in state)
{
if (m.parameters.Count() == 0)
Console.Write($"{m.Id}; ");
else
{
Console.Write($"{m.Id}({string.Join(", ", m.parameters)}); ");
}
}
Console.WriteLine();
}
//B;
//A(num=1);
//A(num=2); B;
//A(num=3); B; A(num=1);
//A(num=4); B; A(num=1); A(num=2); B;
//A(num=5); B; A(num=1); A(num=2); B; A(num=3); B; A(num=1);