; $Id: spiro.pro,v 1.1 1993/04/02 19:43:31 idl Exp $ function gcd, i, j loc_i = i loc_j = j while (loc_j ne 0) do begin temp = loc_j loc_j = loc_i MOD loc_j loc_i = temp; endwhile return, loc_i end pro spiro, stable_rad, rotating_rad, distance, color = color, $ noerase = noerase, linestyle = linestyle ;+ ; NAME: ; SPIRO ; ; PURPOSE: ; Draw "Spirograph" (TM) patterns. ; ; CATEGORY: ; Graphics demo. ; ; CALLING SEQUENCE: ; SPIRO, Stable_Radius, Rotating_Radius [, Distance] ; ; INPUTS: ; Stable_Radius: The radius of the fixed Spirograph "gear" to rotate ; around. ; ; Rotating_Radius: The radius of the moving Spirograph "gear" that is ; rotated around the fixed gear. ; ; Distance: The distance from the center of the rotating gear to ; the pen (?? Hey, it's just a demo... try it and see!). ; ; KEYWORDS: ; None. ; ; OUTPUTS: ; None. ; ; COMMON BLOCKS: ; None. ; ; SIDE EFFECTS: ; Draws a "Spirograph" (TM) pattern on the current window. ; As the original C program states: "The pattern is produced ; by rotating a circle inside of another circle with a pen a ; set distance inside the center of the rotating circle". ; ; EXAMPLE: ; Try the command: ; ; SPIRO, 23, 17, 11 ; ; RESTRICTIONS: ; None. ; ; MODIFICATION HISTORY: ; 22, December, 1989, A.B. Inspired by a C program posted ; to the Internet by Paul Schmidt (2/2/1988). ; ;- size1 = float(stable_rad) size2 = float(rotating_rad) dist = float(distance) if (n_elements(color) eq 0) then color = !p.color if (not keyword_set(linestyle)) then linestyle = 0 if (not keyword_set(noerase)) then erase inc1 = 0.2; if (size1 gt size2) then begin loops = size1 endif else begin loops = size2 endelse loops = 2.0 * !PI * loops / gcd(fix(size1), fix(size2)) if (!d.x_size gt !d.y_size) then begin scale = !d.y_size endif else begin scale = !d.x_size endelse scale = (scale * 0.95 / 2) / (ABS(size1 - size2) + dist) size1 = size1 * scale size2 = size2 * scale dist = dist * scale center_x = !d.x_size/2 -1 center_y = !d.y_size/2 -1 d = size1 - size2 inc2 = inc1 - inc1 * (size1 / size2); a1 = fltarr(1024) a2 = fltarr(1024) a1(0) = (angle1 = 0) a2(0) = (angle2 = 0) n = 1 while (angle1 lt loops) do begin a1(n) = (angle1 = angle1 + inc1) a2(n) = (angle2 = angle2 + inc2) n = n + 1 if (n eq 1024) then begin ; Buffer is full plots, /device, cos(a2) * dist + cos(a1) * d + center_x, $ sin(a2) * dist + sin(a1) * d + center_y, $ color=color, linestyle=linestyle a1(0) = angle1 ; Repeat last point in new buffer a2(0) = angle2 n = 1 endif endwhile ; Output any remaining partial buffer. n = n - 1 if (n gt 0) then begin a1 = a1(0:n) a2 = a2(0:n) plots, /device, cos(a2) * dist + cos(a1) * d + center_x, $ sin(a2) * dist + sin(a1) * d + center_y, $ color=color, linestyle=linestyle endif end