Shape Replacements

John Horigan edited this page Mar 16, 2015 · 2 revisions

The replacement shapes for a rule are listed within the curly braces for the of the rule. A shape replacement consists of a shape specification followed by a shape adjustment. A shape specification can either be the name of a shape or path along with parameters if that shape/path require it; or it can be the name of a variable or parameter that is bound to a shape specification.

shape parentShape {
    childShape1 [ adjustments ]
    childShape2 [ adjustments ]
    childShape3 [ adjustments ]
    childShape4 [ adjustments ]
    childShape5 [ 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 path or a primitive shape (SQUARE, CIRCLE, TRIANGLE, or FILL), 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.

Shape Specifications

A shape specification indicates which shape the shape replacement is targeting. In the simplest case, it is the name of the shape or path. If the named shape or path has parameters then parameter expressions must follow the shape name, and they are part of the shape specification. If a shape specification has been bound to a variable then that variable's name can be a shape specification.

shape foo {
  bar []                     // bar is the shape specification
  aShape = curve(0.98, 0±3)  // curve(0.98, 0±3) is the shape specification, it is
                             //   assigned to the variable aShape
  aShape []                  // aShape is the shape specification
  curve []                   // Error: incomplete shape specification, curve requires two numeric parameters

Parameters in Shape Replacements

If a shape or path takes parameters then they must all be specified when the shape/path is invoked in a shape replacement. The parameter expressions are evaluated and the results are bundled with the shape name and the shape adjustment.

startshape grass[h 120 sat 1 b .5]
shape curve(number shrink, number turn)
  curve(=) [[y 0.5 r turn s shrink y 0.5]]
shape grass {
  loop 100 [x 1]
    curve(rand(0.98, 0.99), rand(-3, 3)) []
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.