############################################################################ # # File: spiro.icn # # Subject: Program to display spirograph lines # # Author: Stephen B. Wampler # # Date: June 17, 1994 # ############################################################################ # # This file is in the public domain. # ############################################################################ # # Version: 1.0 # ############################################################################ # # # Comments: This program displays spirograph-like output # There are two methods of drawing: epitrochoid, where # the secondary circle moves around the outside of the # primary circle, and hypotrochoid (the default here), # where the secondary circle moves around the inside of # the primary circle. # # See the procedure 'helpmsg' for command line options # (or run as 'spiro -help') # # Waits for a window event before closing window # ############################################################################ # # Links: glib, wopen # ############################################################################ # # Requires: Version 9 graphics and co-expressions (for glib.icn) # ############################################################################ link glib # need the turtle graphic stuff link wopen global win, mono, h, w global Window, XMAX, YMAX procedure main (args) local a, b, k, t1, t2, N, arg, use_epi, t, alist XMAX := YMAX := 700 # physical screen size w := h := 350.0 a := 100.0 b := 5.0 k := 20.0 t1 := 0.0 t2 := 1.0 # only roll around once. N := 500 while arg := get(args) do { case arg of { "-help"|"-h" : helpmsg() "-epi" : use_epi := "yes" "-a": a := real(get(args)) "-b": b := real(get(args)) "-k": k := real(get(args)) "-t1": t1 := real(get(args)) "-t2": t2 := real(get(args)) "-N" : N := integer(get(args)) } } win := WOpen("label=Spirograph", "width="||XMAX, "height="||YMAX) mono := WAttrib (win, "depth") == "1" Window := set_window(win, point(-w,-h), point(w,h), viewport(point(0,0), point(XMAX, YMAX), win)) EraseArea(win) t := turtle(Window, point(w/2, h/2), 0, create |"red") # build list of arguments to pass to parametric equations # (same list for both x and y equations here) alist := [a,b,k] if \use_epi then draw_curve(t,epi_x,alist,epi_y,alist,t1,t2,N) else draw_curve(t,hypo_x,alist,hypo_y,alist,t1,t2,N) # sit and wait for an event on the window. Event(win) close(win) end procedure epi_x(t,a[]) static twopi local ab initial twopi := 2*&pi ab := a[1]+a[2] return (ab)*cos(twopi*t) - a[3]*cos(twopi*((ab)*t)/a[2]) end procedure epi_y(t,a[]) static twopi local ab initial twopi := 2*&pi ab := a[1]+a[2] return (ab)*sin(twopi*t) - a[3]*sin(twopi*((ab)*t)/a[2]) end procedure hypo_x(t,a[]) static twopi local ab initial twopi := 2*&pi ab := a[1]-a[2] return (ab)*cos(twopi*t) + a[3]*cos(twopi*((ab)*t)/a[2]) end procedure hypo_y(t,a[]) static twopi local ab initial twopi := 2*&pi ab := a[1]-a[2] return (ab)*sin(twopi*t) - a[3]*sin(twopi*((ab)*t)/a[2]) end procedure helpmsg() write("Usage: Spiro [-a r] [-b r] [-k r] [-t1 r] [-t2 r] [-N n] [-epi]") write() write("where:") write("\t-a r - radius of center circle {default 100}") write("\t-b r - radius of moving circle {5}") write("\t-k r - distance of pen from center of moving circle {20}") write("\t-t1 r - initial value for parameter {0.0}") write("\t-t2 r - final value for parameter {1.0 (one revolutio)}") write("\t-N n - number of intervals to draw {500}") write("\t-epi - use epitrochoid instead of hypotrochoid") stop() end