This commit is contained in:
2025-05-13 04:46:54 +03:00
parent e2b013a9f9
commit 0335ce61c5
48 changed files with 4915 additions and 0 deletions
+211
View File
@@ -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 () {
}
}