___________________________________________________
There is a large class of fractals that Context Free is currently unable to do because there is no way to update a rule's transformation matrix from within the rule. My proposition is for transformations in angle brackets (< >) to be processed like transformations in square brackets ([ ]) but actually update the parent's transformation matrix, instead of restoring it after running the rule. The transform should also be updatable without invoking another rule. For instance, the following should all be equivalent:
Code: Select all
# The old way:
rule OUTLINESQUARE_OLD
{
SQUARE [ y 5 s 1 10 ]
SQUARE [ y 10 r 90 y 5 s 1 10 ]
SQUARE [ y 10 r 90 y 10 r 90 y 5 s 1 10 ]
SQUARE [ y 10 r 90 y 10 r 90 y 10 r 90 y 5 s 1 10]
}
# The new way, style 1:
rule OUTLINESQUARE
{
<y 5>
SQUARE { s 1 10 }
<y 5 r 90 y 5>
SQUARE { s 1 10 }
<y 5 r 90 y 5>
SQUARE { s 1 10 }
<y 5 r 90 y 5>
SQUARE { s 1 10 }
<y 5 r 90>
}
# The new way, style 2:
rule OUTLINESQUARE2
{
SQUARE < y 5 s 1 10 >
SQUARE < s 1 .1 y 5 r 90 y 5 s 1 10 >
SQUARE < s 1 .1 y 5 r 90 y 5 s 1 10 >
SQUARE < s 1 .1 y 5 r 90 y 5 s 1 10 >
< s 1 .1 y 5 r 90 >
}
# The new way, style 3:
rule OUTLINESQUARE3
{
<y 5>
SQUARE { s 1 10 }
CORNER < >
SQUARE { s 1 10 }
CORNER < >
SQUARE { s 1 10 }
CORNER < >
SQUARE { s 1 10 }
<y 5 r 90>
}
rule CORNER
{
<y 5 r 90 y 5>
}
Of course, rules would have to be careful if there were any possibility they were going to be invoked in this way, but any failure (or intentional choice not) to restore the transform to the initial state would be the caller's problem, since invoking such a rule with { } wouldn't propagate the changes to the caller.
A rule's <> behaviour can also be masked, so that even if it is called with <>, no change is made to the caller's matrix:
Code: Select all
rule PROXY
{
INNERRULE {}
}
rule INNERRULE
{
<whatever>
OTHERRULE <whatever>
}
Adding this rule will allow for some L-systems to be written in CFDG, and the suggestion I've seen in another thread for a counter parameter to allow selection of rules based on recursion depth (or the suggestion I made after originally posting this to add parameters to rules) will complete the support.
_____________________________________________________
After thinking through it, this also doesn't seem to break the context free paradigm. Rules will still behave exactly the same way, conforming to the transformation they are given. This syntax is essentially a shorthand for embedding the transformations directly into the transformation lists for the other rules invoked as part of a rule. The fact that my example above can be represented without the new syntax (at the expense of readibility/conciseness) is evidence of this.
This change would also add a degree of reusability/hiding of implementation, in that, for instance, a rule wouldn't need to know the particulars of a font ruleset that it imported in order to use it and place glyphs correctly:
Code: Select all
# Old way:
rule HELLO
{
H_5by5 { x 0.0 }
E_5by5 { x 1.2 }
L_5by5 { x 2.4 }
L_5by5 { x 3.6 }
O_5by5 { x 4.8 }
}
# New way:
rule HELLO2
{
H_5by5 <>
E_5by5 <>
L_5by5 <>
L_5by5 <>
O_5by5 <>
}