turtle.red 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. module turtle;
  2. % REDUCE implementation of Turtle Graphics
  3. % Caroline Cotter, ZIB,Berlin, 1998.
  4. % The main user commands for drawing pictures follow.
  5. load_package gnuplot;
  6. %USER SETTING FUNCTIONS
  7. % The following allow the user to reset the position of the turtle whilst
  8. % drawing a %picture - that is, these commands are to be used when the pen is
  9. % to be lifted and set down at a new point, or to change the direction
  10. % (heading) of the turtle. Since these do not actually draw anything,
  11. % nothing is returned. However, in order %to allow a continuous drawing,
  12. % the latest position of the turtle must be returned
  13. %(otherwise an error is incurred when trying to plot the points).
  14. algebraic<<
  15. procedure setheading(mu); %Redirects the turtle
  16. begin scalar w;
  17. w:=if mu=() then heading
  18. else ck(mu); %remember ck sets between 0 and 360
  19. heading:=w;
  20. return {x_coord,y_coord}
  21. end;
  22. procedure setx(i); %Relocates the turtle in the x-direction
  23. begin;
  24. x_coord:=i;
  25. return {x_coord,y_coord}
  26. end;
  27. procedure sety(j); %Relocates the turtle in the y-direction
  28. begin;
  29. y_coord:=j;
  30. return {x_coord,y_coord}
  31. end;
  32. procedure setposition(q); %Repositions the turtle (takes cartesian
  33. begin; %coordinate as its argument)
  34. x_coord:=first q;
  35. y_coord:=second q;
  36. return {x_coord,y_coord}
  37. end;
  38. % Both turnleft and turnright redirect the turtle,
  39. % dependent on its current direction
  40. procedure turnleft(gamma);
  41. begin;
  42. heading:=ck(heading + gamma);
  43. return {x_coord,y_coord}
  44. end;
  45. procedure turnright(delta);
  46. begin;
  47. heading:=ck(heading - delta);
  48. return {x_coord,y_coord}
  49. end;
  50. procedure setheadingtowards(q); %This takes a cartesian coordinate point as
  51. %its argument and redirects the turtle towards
  52. begin scalar x,y,f; %the point specified.
  53. x:=first q - x_coord;
  54. y:=second q - y_coord;
  55. f:=polar({x,y});
  56. heading:= ck(second f);
  57. return {x_coord,y_coord}
  58. end;
  59. %We also need to use forward/back without drawing a line
  60. %(in addition to the other set commands). These have the effect
  61. % of penup/pendown commands used in conjunction with forward/back.
  62. procedure setforward(m);
  63. begin scalar theta,s,u;
  64. theta:=heading;
  65. s:={m,theta};
  66. u:=cartesian(s);
  67. return setposition(u)
  68. end;
  69. procedure setback(n);
  70. begin scalar theta,v,w;
  71. theta:=ck(heading+180);
  72. v:={n,theta};
  73. w:=cartesian(v);
  74. heading:=ck(theta-180);
  75. return setposition(w)
  76. end;
  77. %LINE-DRAWING FUNCTIONS
  78. % The following functions are used when an actual line is to be drawn
  79. % between two points on the graph. They each return a list of two points which,
  80. % when used within the draw function, are joined together by a line.
  81. % In addition, they reset the position of the turtle,
  82. % but do not alter the direction stored.
  83. procedure move(p); %This takes a cartesian coordinate point as
  84. %its argument and draws a line towards the
  85. begin scalar x,y,line; %specified point
  86. x:=first p;
  87. y:=second p;
  88. line:={{x_coord,y_coord},{x,y}};
  89. x_coord:=x;
  90. y_coord:=y;
  91. return line
  92. end;
  93. procedure forward(c); %The turtle is moved c units in the direction
  94. begin scalar theta,s,u,fl; %of the current heading setting
  95. theta:=heading;
  96. s:={c,theta};
  97. u:=cartesian(s);
  98. fl:= {{x_coord,y_coord},{x_coord+first(u),y_coord+second(u)}};
  99. x_coord:=x_coord+first(u);
  100. y_coord:=y_coord+second(u);
  101. return fl
  102. end;
  103. procedure back(d); %The turtle is moved d units in the opposite
  104. begin scalar theta,v,w,bl; %direction to heading
  105. theta:=ck(heading+180);
  106. v:={d,theta};
  107. w:=cartesian(v);
  108. bl:= {{x_coord,y_coord},{x_coord+first(w),y_coord+second(w)}};
  109. x_coord:=x_coord+first(w);
  110. y_coord:=y_coord+second(w);
  111. heading:=ck(theta-180);
  112. return bl
  113. end;
  114. %PLOTTING PICTURES
  115. % The next functions gather the commands input by the user and turn
  116. % them into a graph output in a gnuplot window;
  117. procedure draw(p); %This is the function the user calls to draw
  118. %the list of commands as a picture. It takes
  119. begin scalar g; %a list as its argument. The items in the list
  120. %are expected to be any of the setting or plot-
  121. %ting functions already outlined.
  122. g:=for each a in p collect a;
  123. plot g
  124. end;
  125. %SUMMARY
  126. % The main variables:
  127. % x_coord
  128. % y_coord
  129. % heading
  130. %are global, so it is advised that these are not altered directly.
  131. % The following functions have been used in order to create the user commands, but they
  132. %cannot be used directly in the draw function:
  133. % degree, rad,
  134. % polar, cartesian,
  135. % ck, try.
  136. %(also the info command is designed to be used outside of a call to draw)
  137. % The following functions are all user commands which can be placed in the list to be
  138. %executed by the draw command:
  139. % clearscreen
  140. % home
  141. % setheading
  142. % setx
  143. % sety
  144. % setposition
  145. % turnleft
  146. % turnright
  147. % setheadingtowards
  148. % setforward
  149. % setback
  150. % move
  151. % forward
  152. % back
  153. % The most important function is the draw function. It takes the list
  154. % of commands and plots the points given.
  155. %NOTE
  156. % When using conditional statements under a call to draw, the final else
  157. % statement must return a point or at least {x_coord,y_coord} if the picture
  158. % is to be continued. Also for statements must include 'collect ' with a
  159. % list of drawing commands. (The variable needs to begin counting from 0
  160. % if it is to be joined onto the previous list %of drawing commands,
  161. % e.g. for i:=0:10 collect{.......}).
  162. % This program is designed to take the "Turtle Graphics" commands and implement
  163. % them in REDUCE.
  164. % Where possible, commands have remained the same, but pen-up & pen-down
  165. % commands are not used. Instead the commands either set the variables
  166. %(which are the x and y coordinates and heading variable), or draw a line.
  167. %STARTING UP
  168. % Many commands have either ordinary cartesian arguments or polar coordinate
  169. % arguments, so we need to be able to transform them all into cartesian to
  170. % plot on an x-y plane. This invovles the use of the pi function, so we
  171. % need floating point accuracy:
  172. %% on rounded;
  173. % The following are the main variables of the program, but the user should not
  174. %attempt to alter them directly. The functions
  175. % 'setx,sety,setposition,setheading' are for that purpose.
  176. x_coord:=0;
  177. y_coord:=0;
  178. heading:=0;
  179. procedure clearscreen(); % This function resets the variables to the
  180. begin; %original position.
  181. plotreset; %If the user has plotkeep on then this will
  182. %clear the current gnuplot window.
  183. x_coord:=0;
  184. y_coord:=0;
  185. heading:=0;
  186. return {x_coord,y_coord}
  187. end;
  188. procedure home(); % This also resets the variables and in general
  189. begin; %is sufficient since gnuplot automatically rep-
  190. x_coord:=0; %laces its windows each time it plots a new
  191. y_coord:=0; %graph.
  192. heading:=0;
  193. return {x_coord,y_coord}
  194. end;
  195. %DEGREE-RADIAN TRANSFORMS
  196. % These functions are called in the commands for drawing graphs.
  197. % The user need not call on either degree or rad for drawing purposes.
  198. procedure degree(theta);
  199. begin scalar a;
  200. a:=theta*180/pi;
  201. return a
  202. end;
  203. procedure rad(mu);
  204. begin scalar b;
  205. b:=mu*pi/180;
  206. return b
  207. end;
  208. %POLAR-CARTESIAN TRANSFORMS
  209. % Again, there is no use for these functions in drawing, but they are needed to
  210. % turn user inputs into x-y coordinate points.
  211. procedure polar(p);
  212. begin scalar x,y,r,theta;
  213. x:=first p;
  214. y:=second p;
  215. r:=(x^2+y^2)^(1/2);
  216. if x>0 then theta:=atan(y/x)
  217. else if x=0 then theta:=sign(y)*pi/2
  218. else theta:=pi+atan(y/x);
  219. return(list(r,degree(theta)))
  220. end;
  221. procedure cartesian(p);
  222. begin scalar r,theta,x,y;
  223. r:=first p;
  224. theta:=rad(second p);
  225. x:=r*cos(theta);
  226. y:=r*sin(theta);
  227. return(list(x,y))
  228. end;
  229. procedure ck(m); %This is a useful function to keep the heading
  230. %variable within the 0-360 range. It is used
  231. begin; %within other functions for controlling the
  232. %heading size - it is not necessary for the
  233. %user to call ck.
  234. if numberp m then <<
  235. if (m>=0 and m<360) then heading:=m;
  236. if (m<0) then ck(360+m);
  237. if (m>=360) then ck(m-360) >>
  238. else rederr "error:ck needs numeric argument";
  239. return heading
  240. end;
  241. >>;
  242. endmodule;
  243. end;