Context Free Art

Shape replacements

From Context Free Art

Jump to: navigation, search

Contents

Shape Replacements

The replacement shapes for a rule are listed within the curly braces for the of the rule. A shape replacement consists of a shape name followed by a list of shape adjustments.

rule parentShape {
    childShape1 { shape adjustments }
    childShape2 { shape adjustments }
    childShape3 { shape adjustments }
    childShape4 { shape adjustments }
    childShape5 { shape adjustments }
}

What this code snippet means is that the rule for drawing a parentShape is to draw a childShape1, ... childShape5, each with a particular set of adjustments with respect to parentShape. Each childShape is in turn drawn by finding a rule for it and replacing it with still more shapes. Unless the child shape is a primitive shape (SQUARE, CIRCLE, or TRIANGLE), in which case it is simply drawn on the canvas.

As you can see from this code snippet above, there is a parent/child relationship between the shape for the rule and the replacement shapes within the rule. The parent shape has a particular color and geometry. Each child shape inherits its parent's color and geometry modified by the shape adjustments for that child.

Under the Hood: The difference between the parent geometry and the child geometry takes the form of an affine transform that transforms the parent's coordinate space into the child's coordinate space. When the CFDG file is parsed the geometric shape adjustments are converted into an affine transform matrix and stored away.

Basic Shape Adjustments vs. Ordered Shape Adjustments

or what is the difference between { ... } and [ ... ]

The simplified manner for handling geometric shape adjustments is to take each adjustment and apply it to create the final shape geometry in a fixed and easy to understand order. In this example:

rule foo {
    bar { x 1 y 2 rot 30 s 2 0.5 skew 10 0 flip 45 }
}

The bar shape is first translated (1, 2), then it is rotated 30 degrees, then it is scaled (2, 0.5), then it is skewed 10 degrees from the y-axis, and finally it is reflected across a 45 degree line. It doesn't matter if you shuffle the adjustments, they are still applied in this fixed order:

rule foo {
    bar { flip 45 x 1 rot 30 y 2 skew 10 0 s 2 0.5 }   // same as above
}

If you have multiple instances of an adjustment (multiple scales, multiple x-axis translates, etc.) then only the last one is used. The other are silently dropped. This translate/rotate/scale/skew/flip (TRSSF) adjustment order simplifies CFDG design by allowing you to not worry about what order you place the adjustments.

But being able to control the order that the adjustments are applied to create the final shape geometry is also very useful and can lead to some powerful idioms. Context Free/CFDG also has a syntax for specifying a list of shape adjustments where the adjustment order is significant:

rule spike {
    SQUARE {}
    spike [ x 0.5 s 0.95 x 0.5 ]
}

Each time the spike rule is drawn it draws a square then draws another spike shifted over by 0.5, shrunk by 0.95, and shifted over again by 0.5, but the second shift is done in the scaled geometry. The end result is a line of shrinking squares that are perfectly abutted edge-to-edge. You can change the scaling from 0.95 to some other value and they will still be perfectly abutted. If you tried to do this in the simple adjustment order:

rule spike {
    SQUARE {}
    spike { x 0.975 s 0.95 }
}

you would have to carefully compute the translation whenever you change the scale. Another useful idiom is to put a rotation before a translation and/or scale to work in polar geometry:

startshape flower
 
rule flower {
    // petals
    CIRCLE [ r  30 x 0.5 s 1 0.25 ]
    CIRCLE [ r  90 x 0.5 s 1 0.25 ]
    CIRCLE [ r 150 x 0.5 s 1 0.25 ]
    CIRCLE [ r 210 x 0.5 s 1 0.25 ]
    CIRCLE [ r 270 x 0.5 s 1 0.25 ]
    CIRCLE [ r 330 x 0.5 s 1 0.25 ]
    //center
    CIRCLE { s 0.25 b 1 }
}

These are just two of many possible ways to use ordered shape adjustments.

There is no order dependence on color coordinate changes (hue, brightness, etc.) so color changes are treated the same in both basic and ordered shape adjustment lists.

Under the Hood: The affine transform matrices for basic and ordered shape adjustments are generated using a single parser. As the parser decodes each shape adjustment it saves it away and also turns it into an affine transform matrix which it multiplies into an accumulated affine transform matrix (starting from the identity transform). For a basic shape adjustment the parser tosses the accumulated transform matrix when it sees the '}' and builds the affine transform matrix by combining the stored adjustments in the TRSSF order. For ordered shape adjustments the parser outputs the accumulated affine transform matrix when it sees the ']'.

Shape Replacement Loops

The code snippet above exhibits a common issue with CFDG files: having many shape replacements in a row that differ only by a few adjustments at the beginning. Editting this can be very tedious and prone to mistakes, so a syntax has been defined for describing a bunch of shape replacements that differ from each other only by a fixed set of adjustments. Here is how the flower rule above would be written with this syntax:

rule flower {
    // petals
    6*{ r 60 } CIRCLE [ r 30 x 0.5 s 1 0.25 ]
    //center
    CIRCLE { s 0.25 b 1 }
}

The syntax is a number, a '*', and a list of shape adjustments, followed by a shape replacement with its own list of shape adjustments. The two shape adjustment lists can be of either type (basic or ordered). This shape replacement loop is logically equivalent to:

rule flower {
    // petals
    CIRCLE [ r 30 x 0.5 s 1 0.25 ]
    CIRCLE [ r 60 r 30 x 0.5 s 1 0.25 ]
    CIRCLE [ r 60 r 60 r 30 x 0.5 s 1 0.25 ]
    CIRCLE [ r 60 r 60 r 60 r 30 x 0.5 s 1 0.25 ]
    CIRCLE [ r 60 r 60 r 60 r 60 r 30 x 0.5 s 1 0.25 ]
    CIRCLE [ r 60 r 60 r 60 r 60 r 60 r 30 x 0.5 s 1 0.25 ]
    //center
    CIRCLE { s 0.25 b 1 }
}

The loop adjustment list can contain color adjustments as well as geometry adjustments.

Views
Personal tools
Navigation
Toolbox
MediaWiki
Attribution-Share Alike 2.5
book coverSee our new book:
Community of Variation