This project is the second illustration of the Mathematica OOP power. In this time, selected example is "Deterministic Context Free (DOL) Systems" presented by John Cicilio from the Wolfram Demonstration Project.
In this case, I'll show an OOP singleton programming style example modifying the original program. By the OOP, we can encapsulate the functions as methods in the class.
First part is the class definition.
(* start of OOP class *)Module[{nam, innerF, stack = {}, xStack,
gBase, delta, theta, startPos, pos, last},
setTheta[nam[t_]] ^:= theta = t;
setDelta[nam[t_]] ^:= delta = t;
setCode[nam[f_]] ^:= innerF = f;
setStartPos[nam[p_]] ^:= pos = p;
getGraph[nam] ^:= gBase;
push[nam[item_]] ^:= AppendTo[stack, item];
pop[nam] ^:= (xStack = Last[stack]; stack = Most[stack]; xStack);
fetch[nam] ^:= (
Do[
Switch[innerF[[i]],
"[", push[nam[{theta, pos}]],
"]", {theta, pos} = pop[nam]; Sow[{pos}],
"+", theta += delta,
"-", theta += -delta,
"f",
Sow[last =
Chop@Map[(pos + #) &, Map[RotationMatrix[theta].# &, gBase]]];
pos = Last[last];
],
{i, 1, Length[innerF]}]
);
deploy[nam] ^:= (
theta = 0;
gBase = {{0, 1}};
pos = {0, 0};
gBase = Flatten[DeleteCases[Reap[fetch[nam]], Null], 3];
);
(* methods interface *)
nprmMethod[type_] := type[nam];
prmdMethod[type_[x_]] := type[nam[x]];
]
(* end of OOP singletone class *)
second part is initialization part
rules = {
{{"f" -> "f[+f]f[-f]f"}, "f"},
{{"f" -> "f[+]f[-f]f"}, "f"},
{{"f" -> "f[+f]f[-f][f]"}, "f"},
{{"f" -> "f-ff--f-f"}, "f-f-f-f"},
{{"L" -> "R+L+R", "R" -> "L-R-L"}, "R"},
{{"L" -> "L+R++R-L--LL-R+", "R" -> "-L+RR++R+L--L-R"}, "L"},
{{"f" -> "f+f-f-f+f"}, "-f"},
{{"f" -> "ff-f-f-f-ff"}, "f-f-f-f"},
{{"f" -> "ff-f-f-f-f-f+f"}, "f-f-f-f"}
};
final part is Manipulation part
Manipulate[
Graphics[Line[
replaceWithRules[t_] :=
StringReplace[t, rules[[replacementRule, 1]]];
firstReplacement =
Nest[replaceWithRules, rules[[replacementRule, 2]],
numberOfIterations];
characters =
Characters[
StringReplace[firstReplacement, {"L" -> "f", "R" -> "f"}]];
(* OOP methods call *)
prmdMethod[setDelta[Pi*angleValue/180.]];
prmdMethod[setStartPos[{0, 0}]];
prmdMethod[setCode[characters]];
nprmMethod[deploy];
Join[{{0, 0}}, nprmMethod[getGraph]]
(* end of OOP methods call *)
], ImageSize -> {400, 400}],
{{numberOfIterations, 1, "iterations"}, {1, 2, 3, 4}},
{{angleValue, 25.7, "angle"}, 0, 90, Appearance -> "Labeled"},
{{angleValue, 25.7, ""}, {20, 22.5, 25.7, 60, 90}},
{{replacementRule, 3, "replacement rule"},
Dynamic[# -> {rules[[#, 2]] , rules[[#, 1]]} & /@
Range[Length[rules]], SynchronousUpdating -> False],
ControlType -> PopupMenu},
TrackedSymbols :> {numberOfIterations, angleValue, replacementRule},
AutorunSequencing -> {1, 2, 3},
SaveDefinitions -> False,
SynchronousUpdating -> False
]