Jonathan Gryak - Programming XML in Java - Project
LSystem Simulator (LSS)
Table of Contents:
Overview:
My project, entitled "L-System Simulator", generates graphical depictions of L-Systems. L-Systems are formal languages with recursive grammars. For this project, I designed a DTD that defines a XML-based markup language for L-Systems (L System Markup Language). The main program, LPlant, given a LSML file, the number of iterations, and various output settings (color, thickness, etc.), draws a plant based on the string generated from the L-System.
L-Systems:
L-Systems have a formal definition, but it is unnecessary to discuss it in this context. Essentially, an L-System is a set of rules that, when applied, generate a string. The first symbol, called the axiom, is the first character in the string. The left side of each rule is called the predecessor. The right side of each rule is called the successor. The string is generated by applying each rule every possible time to the current string for a specified number of iterations. For example, if we have the following L-System:
a: 1
1--->2
2--->23
3--->4
4--->@2
The axiom is 1. Say we decide to generate a string by applying these rules 8 times. The progression is as follows:
| Iteration | Generated String |
| 0 | 1 |
| 1 | 23 |
| 2 | 234 |
| 3 | 234@2 |
| 4 | 234@2@23 |
| 5 | 234@2@23@234 |
| 6 | 234@2@23@234@234@2 |
| 7 | 234@2@23@234@234@2@234@2@23 |
| 8 | 234@2@23@234@234@2@234@2@23@234@2@23@234 |
So, at each iteration, each rule is applied everywhere it can be. Each instance of a predecessor in the string is replaced by its successor. As you can see, the length of the string grows exponentially. This put limitations on how many iterations you can perform.
LSML:
DTD:
Below is the LSML DTD:
<?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT PREDECESSOR (#PCDATA)>
<!ELEMENT SUCCESSOR (#PCDATA)>
<!ELEMENT PRODUCTION (PREDECESSOR, SUCCESSOR)>
<!ENTITY % parameters "
STEP CDATA #REQUIRED
ANGLE CDATA #REQUIRED
WIDTH CDATA #REQUIRED
COLOR CDATA #REQUIRED
">
<!ELEMENT BASIC EMPTY>
<!ATTLIST BASIC
BASIC_START CDATA #REQUIRED
BASIC_END CDATA #REQUIRED
>
<!ELEMENT _3DTURTLE EMPTY>
<!ATTLIST _3DTURTLE
%parameters;
>
<!ELEMENT _2DTURTLE EMPTY>
<!ATTLIST _2DTURTLE
%parameters;
>
<!ELEMENT STOCHASTIC EMPTY>
<!ATTLIST STOCHASTIC
%parameters;
>
<!ELEMENT LSYSTEM ((BASIC | _2DTURTLE | _3DTURTLE | STOCHASTIC), PRODUCTION+)>
<!ATTLIST LSYSTEM
AXIOM CDATA #REQUIRED
ORIENTATION (CENTER | BCENTER) #REQUIRED
>
The rules are comprised of production elements, each of which contains one predecessor and one successor. The root element, lsystem, has two attributes, axiom and orientation. The axiom is the axiom for the l-system, while the orientation can be used to determine how to align the drawing (center or bottom-center). There are four elements, basic, _2dturtle, _3dturtle, and stochastic, that determine how the drawing program should interpret the strings generated from this language.
Parser:
I used the Xerces SAX parser to parse the LSML files.
LSS:
Class Hierarchy:
There are two packages, org.gryak.lss and org.gryak.pair. There are six classes, test, MetaParameters, LSMLParser, LSGenerator, LPlant, and Pair. The hierarchy is arranged from more simple at the top to more complex at the bottom.
Class Descriptions:
| Class | Description | Executable/Arguments |
| test | Class test is provided to test out file parsing and string generation. | Yes, java test FILE ITERATIONS |
| MetaParameters | Used to store information parsed from the LSML file, and to pass the information through the class hierarchy. | No |
| LSMLParser | Implements the SAX parser, parsing the LSML file and storing the information in a MetaParameters object. | No |
| LSGenerator | Given the MetaParameters object from the LSMLParser object, generates a string by applying the given rules a specified number of times | No |
| LPlant | GUI interface used to input arguments, the string is generated using a LSGenerator object, then the program transforms the string into a picture | Yes, use GUI |
| Pair | Type-less container which holds pairs of objects, used to hold the predecessor and successor for each production (rule). | No |
Compiling/Running:
If you want to recompile the classes, expand the lss.jar file first.
Compiling/Running Test:
1.javac -classpath PATH_OF_LSS.JAR; Test.java
2.java -classpath .;PATH_OF_XERCES.JAR Test FILE ITERATIONS
Running the LPlant LSS:
1.java -classpath PATH_OF_XERCES.JAR;PATH_OF_LSS.JAR org.gryak.lss.LPlant
2. Input the arguments at the top of the window.
3. Click the "draw" button.
Clarifications/Limitations:
1. Though the parser supports any lsystem, LPlant can only display basic lsystems
at this time.
2. Except for ls1.lsml (max of 40), do not try to do any more iterations than
30. The string becomes too long and the program will hang.
3. The colors must be in the RGB range (0-255), though the program will tell
you if you put in invalid arguments.
4. Length is determined by the number in the string. Though the parser can handle
any character for the predecessor or successor, pictures can only be made from
ones based on numbers.
Example Outputs:
LS1:
Using file ls1.lsml, with 40 iterations, color (1,31,5), thickness 1, and gradient:

LS1A:
Using file ls1a.lsml, with 30 iterations, color (150,50,20), thickness of 2, centered and gradient:

LS1B:
Using file ls1b.lsml, with 30 iterations, color (0,255,0), and thickness of 2:

LS1C:
Using file ls1c.lsml, with 30 iterations, color (20,60,180), thickness of 2, centered and gradient:
