rule test1 {
grid { skew 45 -45 } // grid1
grid { s 1.414213562373 b 0.5 r -45 } // grid2
}
rule test2 {
grid { skew 45 -45 } // grid1
grid { s 1.414213562374 b 0.5 r -45 } // grid2
}
rule grid {
11* {x 2} { 11* {y 2} SQUARE{ x -10 y -10 } }
}
not much difference between test1 and test2, right?
You might be surprised then (as I was) to realise that in test1 grid2 is drawn on top, but in test2 grid1 is drawn on top.
This makes no sense. It seems if the scale transformation in the second call to grid is less than root 2 (or 1.414213562373...) then grid2 wins, and if it's greater than root 2 grid1 wins.
Would someone care to explain this behaviour? Is it a bug?
Is there anyway to force grid2 to always be drawn after grid1? After all, that's what we would expect given that it is called after grid1!!
Yes there is a way to determine what gets drawn on top. Use "z" shape adjustment to put it in the different layer. Have a browse of the gallery to see how to use it if unsure.... or just try stuff out.
I have done a rough job of explaining CF's behaviour and how it leads to the phenomenon you identified in the gallery post. Since it got truncated, here it is in full:
- - - -
In my discussions with the MVJ & MVM, the order of expansion is what it is, and by definition is correct.
The way it works is that CF keeps a bunch of unexpanded rules, consisting of the rule name, the current position of that rule, and the current scale & orientation (well, a transformation matrix). These unexpanded rules are kept in order of decreasing area-expansion factor (the determinant of the transformation matrix). Those with greatest area-expansion are expanded first. This is apparent in your sample code. In the first, the black grid has matrix [[1,1],[-1,1]] that doubles the area (determinant is 2) whereas the grey grid is scaled by 1.5^2 = 2.25. So the grey gets evaluated first.
The bit that is a bit weird is where there is a tie. There are some designs that rely on the current & historical quirks of the evaluation order.
If you want to force a certain evaluation order, you can hide a rule with a big shape inside a small rule.
If you want to force a certain layering, then use the "z" shape adjustment to put things on different layers.
The confusion is due to the interpretation of the order within rules (the order in which shapes are declared) as being "execution" or "calling" order. If it was, CF would do a depth-first expansion. By keeping a list of "unexpanded" rules (cached to disk for busy designs) CF gives something akin to a breadth-first expansion, moderated by object size.
startshape A
rule A{
//default: stacking ordered by biggest to smallest
B{s .8 y 4}
B{s 1.2 x .5 y 4.5 h 120}
B{s 1.2 x 2 y 4}
B{s 0.8 x 2.5 y 4.5 h 120}
//tricky: fool CF into thinking a big object is actually small
B{s 1 y 2 }
B{s 1.5 x 0.5 y 2.5 h 120}
B{s 1 x 2 y 2}
C{s .5 x 2.5 y 2.5 h 120}
// straightforward: tell CF what layer you want everything on
B{}
B{x .5 y .5 h 120}
B{x 2}
B{x 2.5 y .5 h 120 z 1}
}
rule B{SQUARE{b 1 sat 1}}
rule C{SQUARE{s 3 b 1 sat 1}}