aUCBLogo Demos and Tests / spiro_mike
			
				
			
			;Mike Sandy wrote:
;> Steve Vinter wrote:
;> > Just got started using MSWLogo, and as I've been exploring
;> > I have found any logo-based drawings rendering what you could
;> > draw with spirograph many years ago. Surely someone must
;> > have some functions that do this kind of thing (similar to
;> > what you can do by spinning polygons, but done with curves,
;> > instead).
;> >
;> > Does anyone have any pointers?
;
;I wrote :
;
;> Not in line with course suggested above, but perhaps the 'simplest' way
;>  is to use the equations for the curves (epitrochoids and hypotrochoids).
;
;An alternative method, more in keeping with logo's intrinsic approach, is:
;
;A circle can be constructed by starting the turtle at the centre, moving the
;radial length and storing the position reached. The turtle returns to the
;centre, rotates
;a small angle to the right, moves the radial length, stores the position and
;then
;draws a line to the previous stored point and so on.
;
;The same method can be used for the spirograph.
;
;>From the diagram, there are 2 circles with centres l and s and radii rl_ and
;rs.
;The turtle path is from l to s to A(the point generating the curve).  The
;angles m and n are in the ratio rl_ to rs. The length, sA = h*rs
;where h < =  1 if A is on the radius.
;Since n > m, it is best to increment n otherwise fine details can be lost.
;In the code, angle, n,  is replaced by :ang, m = :ang*:rs/:rl_
;
;---------------
to spiro rs :rl_ h size
   ;;:rs and :rl_ RELATIVELY PRIME INTEGERS, :rl_ can be negative.
   ;; :h > 0
   ;; :size depends on :dr so is replaced by :size1
   cs ht pu
   local [angmax dr size1 posn1 posn ang]
   angmax=:rl_*360
   dr=:rl_-rs
   if dr==0 [show [THE TWO RADII MUST NOT BE EQUAL] STOP]
   size1=abs (size/dr)
   posn1=0
   posn=(list 0 size1 * (dr+rs*h))  ;;STARTING POINT
   ang=0
   repeat 1000 ~
   [   ang=angmax*repcount/1000
      home
      seth ang*rs/:rl_ fd size1*dr
      lt ang
      fd size1*rs*h
      posn1=pos
      pd setpos posn pu 
      posn=posn1
      pu
   ]
   updateGraph
end
to spiro_mike
   setUpdateGraph false
   spiro 2 3 .4 100
   waitms 1000
   spiro 7 2 1.2 100
   waitms 1000
   spiro 12 11 .1 50
   waitms 1000
   for [h 0.1 1 0.01]
   [   spiro 11 17 h 100
   ]
end