Wiki
Download
Manual
Eggs
API
Tests
Bugs
show
edit
history
You can edit this page using
wiki syntax
for markup.
Article contents:
== Outdated egg! This is an egg for CHICKEN 4, the unsupported old release. You're almost certainly looking for [[/eggref/5/linden-scheme|the CHICKEN 5 version of this egg]], if it exists. If it does not exist, there may be equivalent functionality provided by another egg; have a look at the [[https://wiki.call-cc.org/chicken-projects/egg-index-5.html|egg index]]. Otherwise, please consider porting this egg to the current version of CHICKEN. == linden-scheme [[toc:]] Parametric 2L-systems integrated with Scheme. The L-systems defined with this library take a significantly different form from the string-based L-systems described by Lindenmayer. linden-scheme uses a class-based system for defining L-systems. [[image:http://alex-charlton.com/static/images/linden-scheme-tree-example.png|Example tree]] === Requirements * gl-math === Documentation ==== Defining L-systems L-systems in linden-scheme are comprised of two parts: L-systems and rules, which are conceptually analogous to classes and methods, respectively. <macro> (define-rule [CLASS] (RULE-NAME [ARGS] ...) BODY ...)</macro> Defines a rule similar to defining a function, but with an optional {{CLASS}}. If {{CLASS}} is omitted, the rule will be used if no more specific rules are defined – i.e. as a fallback rule. Multiple rules with the same {{RULE-NAME}} may be defined, provided they have different classes (otherwise the previous rule with the same name will be over-written). Rules should return a list of rules in {{(RULE [ARGS] ...)}} form. Any non-list value, when returned, will make evaluation of the rule treated as a no-op. In other words, when the rule is evaluated and a list is returned, the rule being evaluated in the current L-systems (by {{step-l-system}}) will be replaced by the given list of rules. If no list is provided, the rule being evaluated will remain the same. The special form {{branch}} may be included in the list of rules returned by a rule. {{branch}} should contain one or more rules. When {{branch}} is used, the state of the rules contained in the {{branch}} is split off from that of the parent of the {{branch}}. For example, a list returned by a rule may look like: '((leaf 1) (branch (leaf 1) (stem 1) (apex)) (stem 1) (apex)) which describes a leaf, a branch (containing a leaf, stem, and apex), a stem, and an apex. When context-dependant or probabilistic rules are desired, see the macros {{context}} and {{probability}} in the section [[#macros|Macros]]. <macro> (define-render-rule [CLASS] (RULE-NAME [ARGS] ...) BODY ...)</macro> {{define-render-rule}} behaves much like {{define-rule}}, to be used for the rendering of an L-system. Render rules operate by side-effect only. The parameter {{render-target}} is provided to track the object that the L-system is rendering to. See {{render-l-system}} and [[#turtle-graphics|Turtle graphics]]. <macro> (define-l-system CLASS (SUPER-CLASSES ...) (RULE [ARGS] ...))</macro> Defines the class of L-systems named {{CLASS}}. These L-systems will use rules defined for {{CLASS}}, and if none are available, they will inherit those from the classes {{SUPER-CLASSES}}. The rules defined for the super-classes are chosen in order of appearance in the super-classes list. Additionally a function named {{CLASS}} is defined that, when called, returns an L-system of {{CLASS}} with the initial rule {{RULE}}. ==== Stepping and rendering L-systems <procedure> (step-l-system SYSTEM)</procedure> Returns a new L-system, created by evaluating each rule in {{SYSTEM}} according to the rules defined by {{define-rule}} corresponding to the class of the L-system. Any rule that has not been defined by {{define-rule}} for the class or super-classes of the system is ignored. When rules are being evaluated, any state is branched according to {{branch}} statements in the system (see [[#manipulating-state|Manipulating state]]). <procedure> (step-l-system-times N SYSTEM)</procedure> Performs {{step-l-system}} on the given {{SYSTEM}}, {{N}} times. <procedure> (render-l-system SYSTEM RENDER-TARGET)</procedure> Evaluates each rule in the {{SYSTEM}}, in order, given their meanings defined by {{define-render-rule}}. Any rule that has not been defined by {{define-render-rule}} for the class or super-classes of the system is ignored. As with {{step-l-system}}, state is branched according to the {{branch}} statements in the system. The parameter {{render-target}} is set to {{RENDER-TARGET}} at the start of evaluation (see [[#turtle-graphics|Turtle graphics]]). The value of {{render-target}} is returned. ==== Macros <macro> (context (TEST BODY ...) ...)</macro> Similar to a {{cond}} form, but conditional to the context of a given rule. Evaluates {{BODY}} when the context given in {{TEST}} matches the current context of the rule being evaluated. Each {{TEST}} should be of the form: ((PREVIOUS-RULE [ARGS] ...) (NEXT-RULE [ARGS] ...) [: GUARD]) When {{PREVIOUS-RULE}} and {{NEXT-RULE}} match the names of the previous and next rules to the rule being currently evaluated, the associated {{BODY}} is evaluated at the exclusion of all other {{BODY}}s. The supplied {{ARGS}} are symbols that are bound to the values of the arguments of their respective rules. Either {{(PREVIOUS-RULE [ARGS] ...)}} or {{(NEXT-RULE [ARGS] ...)}} may be replaced with a {{*}}, indicating that any rule (including none) may match. If desired, a {{GUARD}} form may be supplied, preceded by a {{:}}. This guard acts as an additional test before a {{BODY}} is evaluated. The guard may use any variables given as {{ARGS}} (as well as any other variables in scope). The last {{TEST}} may consist of the symbol {{else}}, which is unconditionally evaluated. For example: (define-rule (apex) (context (((stem len) * : (> len 2)) '((leaf 1) (branch (leaf 1) (stem 1) (apex)) (stem 1) (apex))) (((stem len) *) #f) (else '((leaf 1) (stem 1) (apex))))) defines a rule ({{apex}}) that creates a new branch when preceded by a {{stem}} whose first parameter ({{len}}) greater than 2, does nothing when preceded by a {{stem}} of length less than or equal to 2, and otherwise creates a new {{leaf}} and {{stem}}. <macro> (probability (PROBABILITY BODY ...) ...)</macro> Similar to a {{cond}} form, but evaluates a clause based on a given probability. {{PROBABILITY}} is expected to be a number less than 1.0, or the symbol {{else}}. The sum of all probabilities should add up to 1.0, or less than 1.0 if an {{else}} clause is used. Otherwise there is a chance that no clauses will be evaluated (in the case that the probabilities add to less than 1.0 and no {{else}} is used) or a clause may never be evaluated (in the case that the probabilities add to more than 1.0). For example: (probability (0.1 '((branch (flower)) (apex))) (0.7 #f) (else '((branch (flower)) (branch (flower)) (apex))) describes a 10% chance of creating a branch with a flower, a 70% chance of doing nothing, and a 20% chance of creating two branches with flowers. ==== Manipulating state While rendering L-systems, it is often desirable to track the state of a number of variables, following the branches in the L-system. In this manner, one can implement any type of turtle graphics system. linden-scheme provides this mechanism through the following three functions: <procedure> (define-state VAR DEFAULT)</procedure> Creates a new state variable named {{VAR}} with the default value {{DEFAULT}}. <procedure> (get-state VAR)</procedure> Returns the value of the state variable {{VAR}}. This is only useful when called within a rule. <procedure> (set-state VAR VALUE)</procedure> Sets the value of the state variable {{VAR}} to {{VALUE}}. This is only useful when called within a rule. ==== Turtle graphics linden-scheme provides a set of functions (often also render rules) that implement the standard turtle-graphics commands typically associated with graphical L-systems. These commands are intended to be a standard foundation for turtle graphics, but do not provide any graphical output mechanism themselves. Rather, they provide a convenient parameter for holding some sort of rendering target, as well as a set of procedures that are used to modify and access the usual geometric qualities: namely translation/rotation matrices and thickness. Two state variables are therefore defined for the turtle graphics system: {{transform-matrix}}, {{rotation-matrix}}, and {{thickness}}, although facilities are provided so they do not need to be accessed through {{get-state}} or {{set-state}}. <parameter> render-target</parameter> Used to hold whatever the render rules are rendering to. Is set by {{render-l-system}}. <procedure> (transform-matrix)</procedure> Returns the current transformation matrix, as modified by calls to {{pitch}}, {{roll}}, {{turn}}, {{move}}, and {{move-forward}}. <procedure> (rotation-matrix)</procedure> Returns the rotation component of the current transformation matrix, as modified by calls to {{pitch}}, {{roll}}, and {{turn}}. <procedure> (pitch ANGLE)</procedure> Transform the current transformation matrix by a rotation of {{ANGLE}} degrees around the x-axis. Also defined as a render rule. <procedure> (roll ANGLE)</procedure> Transform the current transformation matrix by a rotation of {{ANGLE}} degrees around the y-axis. Also defined as a render rule. <procedure> (turn ANGLE)</procedure> Transform the current transformation matrix by a rotation of {{ANGLE}} degrees around the z-axis. Also defined as a render rule. <procedure> (move X Y Z)</procedure> Transform the current transformation matrix by a translation of {{(X Y Z)}}. Also defined as a render rule. <procedure> (move-forward DISTANCE)</procedure> Transform the current transformation matrix by a translation of {{(0 DISTANCE 0)}}. Also defined as a render rule. <procedure> (thickness [X])</procedure> Given the value {{X}}, sets the state variable {{thickness}} to {{X}}. If {{X}} is omitted, the value of {{thickness}} is returned. Also defined as a render rule. <procedure> (grow SCALE)</procedure> Multiplies the value of the state variable {{thickness}} by {{SCALE}}. Also defined as a render rule. === Examples The following is an example of a L-system of a crocus taken from ''The Algorithmic Beauty of Plants'' [[http://algorithmicbotany.org/papers/abop/abop.pdf|(Prusinkiewicz, Lindermayer. 1990)]], section 3.1.3. Note that three different classes ({{crocus}}, {{plant}}, and none) are used in this example. If, for example, a new rule {{stem}} were defined for the class {{crocus}}, it would be used over the {{stem}} rule that is defined for {{plant}}. <enscript highlight="scheme"> (use linden-scheme srfi-1) (define developmental-switch-time 3) (define leaf-growth-limit 4) (define flower-growth-limit 2) (define-rule crocus (apex time) (cond ((< time developmental-switch-time) `((stem 1) (branch (pitch -30) (leaf 0)) (roll 138) (apex ,(add1 time)))) (else '((stem 20) (flower 0))))) (define-rule crocus (flower size) (cond ((< size flower-growth-limit) `((flower ,(add1 size)))))) (define-rule plant (stem length) (cond ((< length 4) `((stem ,(add1 length)))))) (define-rule (leaf size) (cond ((< size leaf-growth-limit) `((leaf ,(add1 size)))))) (define-l-system crocus (plant) (apex 1)) (for-each (lambda (i) (print (step-l-system-times i (crocus)))) (iota 5 1)) </enscript> For another, more visual example corresponding to the image at the top of this document, see the [[https://github.com/AlexCharlton/linden-scheme/tree/master/examples|examples directory]]. === Version history ==== Version 0.2.0 24 April 2016 * Add {{rotation-matrix}} ==== Version 0.1.0 * Initial release === Source repository Source available on [[https://github.com/AlexCharlton/linden-scheme|GitHub]]. Bug reports and patches welcome! Bugs can be reported via GitHub or to alex.n.charlton at gmail. === Author Alex Charlton === License BSD
Description of your changes:
I would like to authenticate
Authentication
Username:
Password:
Spam control
What do you get when you subtract 24 from 8?