*
This commit is contained in:
@@ -0,0 +1,211 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
public class LSystem : MonoBehaviour {
|
||||
public string Premise = "FFFA";
|
||||
|
||||
public string[] Rules = new string[] { "A=!\"[B]////[B]////B", "B=&FFFA" };
|
||||
|
||||
public string ContextIgnore = "F+-";
|
||||
|
||||
public float StepSize = 0.1f;
|
||||
public float StepSizeScale = 0.9f;
|
||||
public float Angle = 28.0f;
|
||||
public float AngleScale = 0.7f;
|
||||
|
||||
public uint Generations = 7;
|
||||
|
||||
private List<List<Vector3>> _branches = new List<List<Vector3>>();
|
||||
|
||||
|
||||
|
||||
// Use this for initialization
|
||||
void Start () {
|
||||
|
||||
}
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
// RebuildTree();
|
||||
}
|
||||
|
||||
private string DrawReductionTree(GOLD.Reduction Root)
|
||||
{
|
||||
//This procedure starts the recursion that draws the parse tree.
|
||||
StringBuilder tree = new StringBuilder();
|
||||
|
||||
tree.AppendLine("+-" + Root.Parent.Text(false));
|
||||
DrawReduction(tree, Root, 1);
|
||||
|
||||
return tree.ToString();
|
||||
}
|
||||
|
||||
private void DrawReduction(StringBuilder tree, GOLD.Reduction reduction, int indent)
|
||||
{
|
||||
//This is a simple recursive procedure that draws an ASCII version of the parse
|
||||
//tree
|
||||
|
||||
int n;
|
||||
string indentText = "";
|
||||
|
||||
for (n = 1; n <= indent; n++) {
|
||||
indentText += "| ";
|
||||
}
|
||||
|
||||
//=== Display the children of the reduction
|
||||
for (n = 0; n < reduction.Count(); n++) {
|
||||
switch (reduction[n].Type()) {
|
||||
case GOLD.SymbolType.Nonterminal:
|
||||
GOLD.Reduction branch = (GOLD.Reduction)reduction[n].Data;
|
||||
|
||||
tree.AppendLine(indentText + "+-" + branch.Parent.Text(false));
|
||||
DrawReduction(tree, branch, indent + 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
string leaf = (string)reduction[n].Data;
|
||||
|
||||
tree.AppendLine(indentText + "+-" + leaf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void RebuildTree(){
|
||||
|
||||
MyParser parser = new MyParser();
|
||||
parser.Setup();
|
||||
|
||||
MemoryStream ms = new MemoryStream(System.Text.ASCIIEncoding.ASCII.GetBytes(@"F(x)=F(7+-x/2)"));
|
||||
StreamReader sr = new StreamReader(ms);
|
||||
|
||||
parser.Parse(sr);
|
||||
var tree = parser.program;
|
||||
var treeTxt = DrawReductionTree(tree);
|
||||
Debug.Log(treeTxt);
|
||||
|
||||
string result = Premise;
|
||||
for(uint g = 0; g < Generations; ++g)
|
||||
{
|
||||
string tmp = "";
|
||||
|
||||
for(int j = 0; j < result.Length; ++j)
|
||||
{
|
||||
string replacement = result[j].ToString();
|
||||
foreach (var rule in Rules)
|
||||
{
|
||||
if(result[j] == rule[0])
|
||||
{
|
||||
replacement = rule.Substring(2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
tmp += replacement;
|
||||
}
|
||||
|
||||
result = tmp;
|
||||
}
|
||||
|
||||
Debug.Log("Final result: " + result);
|
||||
RunTurtle(result);
|
||||
}
|
||||
|
||||
struct TurtleState
|
||||
{
|
||||
public Vector3 position;
|
||||
public Matrix4x4 mat;
|
||||
public List<Vector3> points;
|
||||
}
|
||||
|
||||
void RunTurtle(string commandLine)
|
||||
{
|
||||
Stack<TurtleState> states = new Stack<TurtleState>();
|
||||
|
||||
|
||||
TurtleState state = new TurtleState();
|
||||
state.mat = Matrix4x4.identity;
|
||||
state.position = Vector3.zero;
|
||||
|
||||
_branches.Clear();
|
||||
state.points = new List<Vector3>();
|
||||
state.points.Add(state.position);
|
||||
|
||||
for(int i = 0; i < commandLine.Length; ++i)
|
||||
{
|
||||
char cmd = commandLine[i];
|
||||
|
||||
if(cmd == 'F')
|
||||
{
|
||||
state.position = state.position + state.mat.MultiplyVector(Vector3.up);
|
||||
state.points.Add(state.position);
|
||||
}else if(cmd == '+')
|
||||
{
|
||||
state.mat = state.mat * Matrix4x4.Rotate(Quaternion.Euler(0, 0, -Angle)) ;
|
||||
}
|
||||
else if (cmd == '-')
|
||||
{
|
||||
state.mat = state.mat * Matrix4x4.Rotate(Quaternion.Euler(0, 0, Angle));
|
||||
}
|
||||
else if (cmd == '[')
|
||||
{
|
||||
states.Push(state);
|
||||
state.points = new List<Vector3>();
|
||||
state.points.Add(state.position);
|
||||
}
|
||||
else if (cmd == ']')
|
||||
{
|
||||
state = states.Pop();
|
||||
_branches.Add(state.points);
|
||||
}
|
||||
else if (cmd == '/')
|
||||
{
|
||||
state.mat = state.mat * Matrix4x4.Rotate(Quaternion.Euler(0, -Angle, 0));
|
||||
}
|
||||
else if (cmd == '\\')
|
||||
{
|
||||
state.mat = state.mat * Matrix4x4.Rotate(Quaternion.Euler(0, Angle, 0));
|
||||
}
|
||||
else if (cmd == '&')
|
||||
{
|
||||
state.mat = state.mat * Matrix4x4.Rotate(Quaternion.Euler(Angle, 0, 0));
|
||||
}
|
||||
else if (cmd == '^')
|
||||
{
|
||||
state.mat = state.mat * Matrix4x4.Rotate(Quaternion.Euler(-Angle, 0, 0));
|
||||
}
|
||||
}
|
||||
_branches.Add(state.points);
|
||||
}
|
||||
|
||||
private void OnDrawGizmos()
|
||||
{
|
||||
|
||||
Gizmos.matrix = transform.localToWorldMatrix;
|
||||
|
||||
foreach(var branch in _branches)
|
||||
{
|
||||
if(branch.Count > 1)
|
||||
{
|
||||
for (int i = 0; i < branch.Count - 1; ++i)
|
||||
{
|
||||
Gizmos.DrawLine(branch[i], branch[i + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Update is called once per frame
|
||||
void Update () {
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user