/*
* reeds.cfdg
* by Joel Neely
*
* One of my more ambitious projects to date.
*
* More complex code than I'd like;
* I'm really wishing for constant definition
* and shape parameters,
* but it's a poor workman who blames his tools! ;-)
*
* The heavy commenting is my penance;
* I hope it will be helpful to newcomers
* to see a completely-described example.
*/
startshape start
rule start {
earth {}
sky {}
back {z -1 a -0.99 hue 145 sat 0.25 b 0.5}
reeds {z 1}
}
/*
* MAJOR BACKGROUND SHAPES
*/
rule earth { paint {h 210 b 0.65 sat 0.6} }
rule sky { paint {h 55 b 0.45 sat 0.5 f 0} }
/*
* Recursive background painting,
* shared by earth and sky, intended to
* compress and strengthen successive areas.
*/
rule paint {
SQUARE { y 1.22 s 8 2.5 a -0.45}
paint { y 2.5 b -0.15 sat 0.5 s 0.99 0.6 a 0.15}
}
/*
* MINOR BACKGROUND SHAPES:
*
* Faint, vague horizontal texture;
* added on a whim; comment out the
* use of "back" in "start" to remove.
*/
rule back {
band {}
backup {h 10 sat 0.1 a 0.25}
backdown{ h -10 sat 0.1 a 0.25}
}
/*
* Create a single horizontal band
* with random overlaps.
*/
rule band {
bandit {}
bandx {a -0.2}
}
/*
* Standard "stacked recursion" technique,
* in which each recursive layer modifies
* an aspect used by lower layers.
*/
rule bandx { bandy {x 0.1} }
rule bandx { bandy {x -0.1} }
rule bandx { bandy {x 0.1} bandy {x -0.1} }
rule bandy { bandit {y 0.1} }
rule bandy { bandit {y -0.1} }
rule bandy { bandit {y 0.1} bandit {y -0.1} }
rule bandit { CIRCLE {s 4 0.5} }
/*
* Lower sub-band is vertical mirror of upper.
*/
rule backdown {backup {f 0} }
/*
* Sub-band may be flipped or shifted
* but will always be flattened.
*
* I got lazy here and used self-recursion
* on "backup" and "flatten" to mix in the
* random variations; stacking would have
* made this a bit clearer, at the cost of
* more bulky code.
*/
rule backup { backup {f 90} }
rule backup { flatten {} }
rule backup { flatten {x 0.5} }
rule flatten { flatten {y 0.2} }
rule flatten { flatten {y -0.2} }
rule flatten { back {y 2 s 1.01 0.25} }
/*
* FOREGROUND SHAPES:
*
* Construct a diminishing set of reeds,
* with fronds above and roots below.
*/
rule reeds {
grow {f 0 h 70 sat 1 b 0.2} // fronds up
grow {h 50 sat 1 b 0.2} // roots down
reedsx {x 1 s 0.9 b 0.01} // next reed
}
/*
* Again, using stacked recursion,
* for adjustments to horizontal and
* vertical position, and curvature
* of next reed.
*/
rule reedsx 1 { reedsxx {x -0.4} }
rule reedsx 1 { reedsxx {} }
rule reedsx 1 { reedsxx {x 0.4} }
rule reedsxx 1 { reedsy {x 0.1} }
rule reedsxx 1 { reedsy {x -0.1} }
rule reedsy 1 { reedsf {y 0.1} }
rule reedsy 1 { reedsf {} }
rule reedsy 1 { reedsf {y -0.1} }
rule reedsf 4 { reeds {f 90} }
rule reedsf 1 { reeds {} }
/*
* Here's where I'd really like a language
* feature for defined constants. There's
* a separate definition for each level of
* "raggedness"; changing the subrule
* invoked by "grow" will cause the same
* set of parameters to be used throughout
* the growth of a reed.
*/
rule grow { grow3 { s 0.9 a 0.05 b 0.01 } }
rule grow3 {
CIRCLE {s 0.1 1.9}
grower {x 0 y -0.5 r 3 }
}
rule grow6 {
CIRCLE {s 0.1 1.5}
grower {x 0.015 y -0.53 r 6 }
}
rule grow9 {
CIRCLE {s 0.1 1.1}
grower {x 0.03 y -0.56 r 9 }
}
rule grow12 {
CIRCLE {s 0.1 0.7}
grower {x 0.045 y -0.59 r 12 }
}
/*
* Randomly change curvature direction,
* branch, or just keep going.
*/
rule grower 2 { grow {f 90} }
rule grower 1 { grow {} grow {f 90} }
rule grower 2 { grow {} }