home *** CD-ROM | disk | FTP | other *** search
/ ftp.cs.arizona.edu / ftp.cs.arizona.edu.tar / ftp.cs.arizona.edu / icon / historic / v941.tgz / icon.v941src.tar / icon.v941src / ipl / gprogs / linden.icn < prev    next >
Text File  |  2000-07-29  |  6KB  |  214 lines

  1. ############################################################################
  2. #
  3. #    File:     linden.icn
  4. #
  5. #    Subject:  Program to generate sentences in 0L-systems
  6. #
  7. #    Author:   Ralph E. Griswold
  8. #
  9. #    Date:     June 21, 1999
  10. #
  11. ############################################################################
  12. #
  13. #   This file is in the public domain.
  14. #
  15. ############################################################################
  16. #
  17. #  This program reads in a 0L-system (Lindenmayer system) consisting of
  18. #  rewriting rules in which a string is rewritten with every character
  19. #  replaced simultaneously (conceptually) by a specified string of
  20. #  symbols.
  21. #
  22. #  Rules have the form
  23. #
  24. #    S->SSS...
  25. #
  26. #  where S is a character.
  27. #
  28. #  In addition to rules, there are keywords that describe the system and how
  29. #  to draw it.  These include the "axiom" on which rewriting is started and
  30. #  optionally the angle in degrees between successive lines (default 90).
  31. #  Other keywords may be present, but are ignored.
  32. #
  33. #  Keywords are followed by a colon.
  34. #
  35. #    An example 0L-system is:
  36. #
  37. #    X->-FX++FY-
  38. #    Y->+FX--FY+
  39. #    F->
  40. #    -->-
  41. #    +->+
  42. #    axiom:FX
  43. #    angle:45.0
  44. #    xorg:100
  45. #    yorg:100
  46. #
  47. #  Here, the initial string is "FX" and angular increment is 45 degrees.
  48. #  Note that "-" is a legal character in a 0L-system -- context determines
  49. #  whether it's 0L character or part of the "->" that stands for "is
  50. #  replaced by".
  51. #
  52. #  If no rule is provided for a character, the character is not changed
  53. #  by rewriting. Thus, the example above can be expressed more concisely
  54. #  as
  55. #
  56. #    X->-FX++FY-
  57. #    Y->+FX--FY+
  58. #    F->
  59. #    axiom:FX
  60. #    angle:45.0
  61. #
  62. #  The recognized keywords are:
  63. #
  64. #    axiom    axiom for generation
  65. #    angle    angular increment for turns
  66. #    length    segment length
  67. #    xorg    x origin
  68. #    yorg    y origin
  69. #    comment    comment; ignored
  70. #
  71. #  Distances increase from left to right in the x direction and from top
  72. #  to bottom in the y direction.
  73. #
  74. #  As pure-production systems, the characters are symbolic and have no
  75. #  meaning.  When interpreted for drawing, the characters have the
  76. #  following meaning:
  77. #
  78. #    F    move forward by length
  79. #    f    move backward by length
  80. #    +    turn right by angle
  81. #    -    turn left by angle
  82. #    [    save current state
  83. #    ]    restore current state
  84. #
  85. #  The file containing the 0L-systems is read from standard input.
  86. #
  87. #  The command-line options are:
  88. #
  89. #    -g i    number of generations, default 3
  90. #    -l i    length of line segments, default 5
  91. #    -a i    angular increment in degrees (overrides angle given in
  92. #          the grammar)
  93. #    -w i    window width
  94. #    -h i    window height
  95. #    -x i    initial x position, default mid-window
  96. #    -y i    initial y position, default mid-window
  97. #    -W    write out string instead of drawing
  98. #    -s    take snapshot of image.
  99. #    -d i    delay in milliseconds between symbol interpretations;
  100. #          default 0
  101. #
  102. #  NOTE:  The name option that supported multiple L-Systems in
  103. #         one file has been eliminated on the grounds that it
  104. #         introduced too much complexity in use.
  105. #
  106. ############################################################################
  107. #
  108. #  References:
  109. #
  110. #     Formal Languages, Arto Salomaa, Academic Press, 1973. pp. 234-252.
  111. #
  112. #     The Algorithmic Beauty of Plants, Przemyslaw Prusinkiewicz and
  113. #     Aristid Lindenmayer, Springer Verlag, 1990.
  114. #
  115. #     Lindenmayer Systems, Fractals, and Plants, Przemyslaw Prusinkiewicz and
  116. #     James Hanan, Springer Verlag, 1989.
  117. #
  118. ############################################################################
  119. #
  120. #  See linden.dat for an example of input data.
  121. #
  122. ############################################################################
  123. #
  124. #  Requires:  graphics if drawing
  125. #
  126. ############################################################################
  127. #
  128. #  Links: linddraw, options, wopen
  129. #
  130. ############################################################################
  131.  
  132. link linddraw
  133. link options
  134. link wopen
  135.  
  136. procedure main(args)
  137.    local line, gener, axiom, angle, opts, i, s, c, symbol, rewrite
  138.    local allchars, rhs, value, spec, x, y, length, w, h, delay, name
  139.  
  140.    rewrite := table()
  141.    allchars := ''            # cset of all rhs characters
  142.  
  143.    opts := options(args,"g+l+a+w+h+x+y+Wsd+")
  144.  
  145.    rhs := ''
  146.  
  147.    while line := read() do
  148.       line ? {
  149.          if symbol := move(1) & ="->" then {
  150.             rhs := tab(0)
  151.             rewrite[symbol] := rhs
  152.             allchars ++:= rhs            # keep track of all characters
  153.             }
  154.          else if spec := tab(upto(':')) then {
  155.             move(1)
  156.             value := tab(0)
  157.             case spec of {
  158.                "axiom":    {
  159.                   axiom := value
  160.                   allchars ++:= rhs        # axiom might have strays
  161.                   }
  162.                "angle":    angle := value
  163.                "xorg":     x := value
  164.                "yorg":     y := value
  165.                "comment":  &null        # ignore comments
  166.                "length":   length := value   
  167.                "gener":    gener := value   
  168.                "name":     name := value
  169.                }                # ignore others
  170.             }
  171.          else write(&errout, "malformed input: ", tab(0))
  172.          }
  173.  
  174. #  At this point, we have the table to map characters, but it may lack
  175. #  mappings for characters that "go into themselves" by default.  For
  176. #  efficiency in rewriting, these mappings are added.
  177.  
  178.    every c := !allchars do
  179.      /rewrite[c] := c
  180.  
  181.    h := \opts["h"] | 400
  182.    w := \opts["w"] | 400
  183.  
  184.    angle := \opts["a"]            # command-line overrides
  185.    length := \opts["l"]
  186.    gener := \opts["g"]
  187.    x := \opts["x"]
  188.    y := \opts["y"]
  189.    delay := \opts["d"]
  190.  
  191.    /angle := 90                # defaults
  192.    /length := 5
  193.    /gener := 3
  194.    /x := 0
  195.    /y := 0
  196.    /delay := 0
  197.    /name := "intitled"
  198.  
  199.    if /axiom then stop("*** no axiom")
  200.  
  201.    if /opts["W"] then {
  202.       WOpen("size=" || w || "," || h, "dx=" || (w / 2),
  203.       "dy=" || (h / 2)) | stop("*** cannot open window")
  204.       linddraw(x, y, axiom, rewrite, length, angle, gener, delay)
  205.       if \opts["s"] then WriteImage(name || ".gif")
  206.       WDone()
  207.       }
  208.    else {
  209.       every writes(lindgen(!axiom, rewrite, gener))
  210.       write()
  211.       }
  212.  
  213. end
  214.