 |
       |
| |
Part III
|
|
Simple system - particle system |
|
L-system and turtle graphics |
|
Complex system - cellular automata |
|
| |
| Understanding language, L-System |
String : concatenation of alphabets (symbols).
Axiom : the first initial symbol(s).
Production rules : the description of how one string of symbols generate another.
Let's try out one example
Alphabets: F, -, +
Axiom: F
Rules: F -> F + F - - F + F |
The first generation is : F+F--F+F
The second generation is : F+F--F+F + F+F--F+F - - F+F--F+F + F+F--F+F
The symbols are pure syntactic at this moment. We have not come with any meaning or semantics. In the later section, we give 'meaning' to each of the symbol.
|
| Use language to describe graphics |


It is not easy to structurally to describe a common plant found in nature. Aristid Lindenmayer, a biologist in 1968 derived a formal method to describe the growth of plants.
Take a look of this language.
Alphabets: F, B, -, +, [, ]
Axiom: B
Rules: B -> F
B -> F[-B]+B |
|
| Turtle graphics |
In primary school, we come across the use of Logo to draw computer graphics with just a few commands.
Command |
Explanation |
F |
Draw forward by a fixed length |
f |
Move forward by a fixed length |
+ |
Turn anti-clockwise for a fixed angle |
- |
Turn clockwise for a fixed angle |
[ |
Store the current position and direction |
] |
Restore the last stored position and direction |
Use the following Processing classes to implement and try out some turtle graphics operations.
To use the Turtle class, define an instance of it.
Initialize it in the setup() function. It needs 4 parameters, namely, the initial x, initial y, initial direction, increment angle.
t1 = new Turtle(width/2,height/2,0,30); |
The methods are:
Function |
Explanation |
mark(_l) |
Draw forward by a fixed length |
move(_l) |
Move forward by a fixed length |
left() |
Turn anti-clockwise for a fixed angle |
right() |
Turn clockwise for a fixed angle |
push() |
Store the current position and direction |
pop() |
Restore the last stored position and direction |
turn(_a) |
Turn a specified angle |
|
| Simple exercises |
Draw a square.
t1.mark(100);
t1.turn(90);
t1.mark(100);
t1.turn(90);
t1.mark(100);
t1.turn(90);
t1.mark(100); |
Or put it in a function.
void shape() {
for (int i=0;i<4;i++) {
t1.mark(100);
t1.turn(90);
}
} |
Or put it in a function with parameter.
void shape(float _l) {
for (int i=0;i<4;i++) {
t1.mark(_l);
t1.turn(90);
}
} |
Guess what will be the graphics? Try it out. Is it what you expect?
void shape() {
for (int i=0;i<360;i++) {
t1.mark(1);
t1.turn(1);
}
} |
Use a more general form. Try this one.
void shape(int _c, float _l, float _a) { for (int i=0;i<_c;i++) { t1.mark(_l); t1.turn(_a); } } |
Introduce a little more complexity.
void shape(int _c, float _l, float _a) { for (int i=0;i<_c;i++) { t1.mark(_l); t1.turn(_a);
t1.mark(_l);
t1.turn(_a*2); } } |
|
| Recursion |
To generate more complex graphics, we can use recursive functions.
void shape(float _l, float _a, int _c) { if (_c>0) { t1.mark(_l); t1.turn(_a); shape(_l+1, _a, _c-1); } } |
Note that within the shape() function, it calls itself. That can be against intuition.
Note also that, in the shape() function, there is a if statement to guard against an infinitive call of itself. For every recursive call, the parameter _c will be decremented by 1 until it reaches 0. Without this, the function will never end and cause error in your program.
More fun with recursion.
void shape(float _l, float _a, float _i, int _c) { if (_c>0) { t1.mark(_l); t1.turn(_a); shape(_l+_i, _a, _i, _c-1); } } |

void shape(float _l, float _a, float _i, int _c) { if (_c>0) { t1.mark(_l); t1.turn(_a); shape(_l, _a+_i, _i, _c-1); } } |

|
| Koch curve example |




For every recursion, the line segment repeats itself. The basic construction is:
t1.mark(len);
t1.left();
t1.mark(len);
t1.right();
t1.right();
t1.mark(len);
t1.left();
t1.mark(len);
|
Use recursive program to implement a function to generate a koch curve.
|
| Tree |
How to draw a tree? We start with a simple one.

t1.mark(len);
t1.push();
t1.left();
t1.mark(len);
t1.pop();
t1.right();
t1.mark(len); |



We can define a function tree() to draw a tree. It will have 2 parameters, one for the length of the branch and the other is the depth you like to draw.
tree(float _l, int _d)
t1.mark(_l);
t1.push();
t1.left();
t1.mark(_l);
tree(?, ?);
t1.pop();
t1.right();
t1.mark(_l);
tree(?, ?); |
To have a more natural appearance, you can introduce randomness in the length or the branch angle.


If we take away the noLoop() and re-start the Turtle graphics system at each draw(), we can have an animated image of the tree.
|