home *** CD-ROM | disk | FTP | other *** search
/ BURKS 2 / BURKS_AUG97.ISO / BURKS / LANGUAGE / SMALTALK / TEXTBOOK / AP14.ST (.txt) < prev    next >
Text File  |  1997-04-22  |  7KB  |  299 lines

  1.  
  2. 'Smalltalk Textbook Appendix 14'!
  3.  
  4.  
  5.  
  6.  
  7.  
  8. Object subclass: #EngiTurtle
  9.     instanceVariableNames: 'location direction down nib color gstate '
  10.     classVariableNames: ''
  11.     poolDictionaries: ''
  12.     category: 'Engi-Geometric'!
  13. EngiTurtle comment:
  14. '
  15.  
  16. Engi 0.04 (8 February 1994)
  17. Copyright (C) 1994 by Atsushi Aoki
  18.  
  19. '!
  20.  
  21.  
  22. !EngiTurtle methodsFor: 'initialize-release'!
  23.  
  24. initialize
  25.     location := 0 @ 0.
  26.     direction := 0.
  27.     down := true.
  28.     gstate := nil! !
  29.  
  30. !EngiTurtle methodsFor: 'accessing'!
  31.  
  32. color
  33.     ^color!
  34.  
  35. color: colorValue 
  36.     color := colorValue!
  37.  
  38. direction
  39.     ^direction!
  40.  
  41. direction: degrees 
  42.     direction := degrees \\ 360!
  43.  
  44. graphicsContext
  45.     ^gstate!
  46.  
  47. graphicsContext: graphicsContext 
  48.     graphicsContext notNil ifTrue: [gstate := graphicsContext copy]!
  49.  
  50. location
  51.     ^location!
  52.  
  53. location: aPoint 
  54.     location := aPoint!
  55.  
  56. nib
  57.     ^nib!
  58.  
  59. nib: anInteger 
  60.     nib := anInteger asInteger max: 0! !
  61.  
  62. !EngiTurtle methodsFor: 'testing'!
  63.  
  64. canDraw
  65.     ^self graphicsContext notNil!
  66.  
  67. isDown
  68.     ^down = true!
  69.  
  70. isUp
  71.     ^self isDown not! !
  72.  
  73. !EngiTurtle methodsFor: 'moving'!
  74.  
  75. down
  76.     down := true!
  77.  
  78. east
  79.     self direction: 0!
  80.  
  81. go: distance 
  82.     | dir |
  83.     direction = 0 ifTrue: [^self goto: location + (distance @ 0)].
  84.     direction = 90 ifTrue: [^self goto: location + (0 @ distance)].
  85.     direction = 180 ifTrue: [^self goto: location - (distance @ 0)].
  86.     direction = 270 ifTrue: [^self goto: location - (0 @ distance)].
  87.     dir := direction degreesToRadians.
  88.     dir := dir cos @ dir sin.
  89.     self goto: dir * distance + location!
  90.  
  91. goto: aPoint 
  92.     | old |
  93.     old := self location.
  94.     self location: aPoint.
  95.     self drawLineFrom: old to: aPoint!
  96.  
  97. home
  98.     self canDraw
  99.         ifTrue: [self place: self graphicsContext medium bounds center]
  100.         ifFalse: [self place: 0 @ 0]!
  101.  
  102. north
  103.     self direction: 270!
  104.  
  105. place: aPoint 
  106.     self location: aPoint!
  107.  
  108. south
  109.     self direction: 90!
  110.  
  111. turn: degrees 
  112.     self direction: self direction + degrees!
  113.  
  114. up
  115.     down := false!
  116.  
  117. west
  118.     self direction: 180! !
  119.  
  120. !EngiTurtle methodsFor: 'converting'!
  121.  
  122. asImage
  123.     self canDraw
  124.         ifTrue: [^self graphicsContext medium asImage]
  125.         ifFalse: [^nil]! !
  126.  
  127. !EngiTurtle methodsFor: 'designs'!
  128.  
  129. dragon: orderNumber distance: distance 
  130.     orderNumber = 0
  131.         ifTrue: [self go: distance]
  132.         ifFalse: [orderNumber > 0
  133.                 ifTrue: 
  134.                     [self dragon: orderNumber - 1 distance: distance.
  135.                     self turn: 90.
  136.                     self dragon: 1 - orderNumber distance: distance]
  137.                 ifFalse: 
  138.                     [self dragon: -1 - orderNumber distance: distance.
  139.                     self turn: -90.
  140.                     self dragon: 1 + orderNumber distance: distance]]!
  141.  
  142. mandala: npoints diameter: d 
  143.     | l points |
  144.     l := (3.14 * d / npoints) rounded.
  145.     self home; up; turn: -90; go: d // 2; turn: 90; go: 0 - l // 2.
  146.     points := Array new: npoints.
  147.     1 to: npoints do: 
  148.         [:i | 
  149.         points at: i put: location rounded.
  150.         self go: l; turn: 360 // npoints].
  151.     self down.
  152.     npoints // 2
  153.         to: 1
  154.         by: -1
  155.         do: [:i | 1 to: npoints do: 
  156.                 [:j | 
  157.                 self place: (points at: j).
  158.                 self goto: (points at: j + i - 1 \\ npoints + 1)]]!
  159.  
  160. spiral: n angle: a 
  161.     1 to: n do: [:i | self go: i; turn: a]! !
  162.  
  163. !EngiTurtle methodsFor: 'private'!
  164.  
  165. drawLineFrom: startPoint to: endPoint 
  166.     | graphicsContext |
  167.     graphicsContext := self graphicsContext.
  168.     (self canDraw and: [self isDown])
  169.         ifTrue: 
  170.             [graphicsContext lineWidth: self nib.
  171.             graphicsContext paint: self color.
  172.             graphicsContext capStyle: GraphicsContext capRound.
  173.             graphicsContext joinStyle: GraphicsContext joinRound.
  174.             graphicsContext displayLineFrom: startPoint to: endPoint]! !
  175. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  176.  
  177. EngiTurtle class
  178.     instanceVariableNames: ''!
  179.  
  180.  
  181. !EngiTurtle class methodsFor: 'instance creation'!
  182.  
  183. new
  184.     | turtle |
  185.     turtle := super new initialize.
  186.     turtle graphicsContext: nil.
  187.     turtle home.
  188.     ^turtle!
  189.  
  190. on: graphicsContext 
  191.     | turtle |
  192.     turtle := super new initialize.
  193.     turtle graphicsContext: graphicsContext.
  194.     turtle home.
  195.     ^turtle! !
  196.  
  197. !EngiTurtle class methodsFor: 'examples'!
  198.  
  199. example1
  200.     "EngiTurtle example1."
  201.  
  202.     | window turtle start |
  203.     window := ScheduledControllers activeController view.
  204.     turtle := EngiTurtle new.
  205.     turtle nib: 8; color: ColorValue red.
  206.     turtle graphicsContext: window graphicsContext.
  207.     window clear.
  208.     turtle home.
  209.     start := turtle location.
  210.     turtle east; turn: 30; go: 60.
  211.     turtle turn: 90.
  212.     30 * 2 timesRepeat: [turtle go: 60 * 2 * 3.14159 / (36 * 2); turn: 10 / 2].
  213.     turtle goto: start.
  214.     window sensor waitClickButton.
  215.     window display!
  216.  
  217. example2
  218.     "EngiTurtle example2."
  219.  
  220.     | window turtle |
  221.     window := ScheduledControllers activeController view.
  222.     turtle := EngiTurtle new.
  223.     turtle nib: 2; color: ColorValue red.
  224.     turtle graphicsContext: window graphicsContext.
  225.     window clear.
  226.     turtle home.
  227.     turtle dragon: 10 distance: 5.
  228.     window sensor waitClickButton.
  229.     window display!
  230.  
  231. example3
  232.     "EngiTurtle example3."
  233.  
  234.     | window turtle size |
  235.     window := ScheduledControllers activeController view.
  236.     turtle := EngiTurtle new.
  237.     turtle nib: 4; color: ColorValue red.
  238.     size := window bounds width min: window bounds height.
  239.     turtle graphicsContext: window graphicsContext.
  240.     window clear.
  241.     turtle home.
  242.     turtle spiral: size * (4 / 5) angle: 144.
  243.     window sensor waitClickButton.
  244.     window display!
  245.  
  246. example4
  247.     "EngiTurtle example4."
  248.  
  249.     | window turtle size |
  250.     window := ScheduledControllers activeController view.
  251.     turtle := EngiTurtle new.
  252.     turtle nib: 1; color: ColorValue red.
  253.     size := window bounds width min: window bounds height.
  254.     turtle graphicsContext: window graphicsContext.
  255.     window clear.
  256.     turtle home.
  257.     turtle mandala: 24 diameter: size - 20.
  258.     window sensor waitClickButton.
  259.     window display!
  260.  
  261. example5
  262.     "EngiTurtle example5."
  263.  
  264.     | window creator turtle1 turtle2 turtle3 turtle4 turtle5 box size promise spiral |
  265.     window := ScheduledControllers activeController view.
  266.     creator := [(EngiTurtle new) nib: 1; color: ColorValue red; yourself].
  267.     turtle1 := creator value.
  268.     turtle2 := creator value.
  269.     turtle3 := creator value.
  270.     turtle4 := creator value.
  271.     turtle5 := creator value.
  272.     window clear.
  273.     box := window bounds.
  274.     size := (box width min: box height)
  275.                 // 3.
  276.     promise := Semaphore new.
  277.     spiral := 
  278.             [:turtle | 
  279.             1 to: size
  280.                 do: 
  281.                     [:i | 
  282.                     turtle graphicsContext: window graphicsContext.
  283.                     turtle go: i; turn: 89.
  284.                     Processor yield].
  285.             promise signal].
  286.     turtle1 place: (box topLeft corner: box center) center; direction: 0.
  287.     turtle2 place: (box topCenter corner: box rightCenter) center; direction: 0.
  288.     turtle3 place: (box leftCenter corner: box bottomCenter) center; direction: 0.
  289.     turtle4 place: (box center corner: box bottomRight) center; direction: 0.
  290.     turtle5 place: box center; direction: 0.
  291.     [spiral value: turtle1] fork.
  292.     [spiral value: turtle2] fork.
  293.     [spiral value: turtle3] fork.
  294.     [spiral value: turtle4] fork.
  295.     [spiral value: turtle5] fork.
  296.     promise wait; wait; wait; wait; wait.
  297.     window sensor waitClickButton.
  298.     window display! !
  299.