summaryrefslogtreecommitdiff
path: root/ipl/gprogs/spiro.icn
blob: 42ac1b30f0b1d6262f16db8f4e498e6b8b6ccd13 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
############################################################################
#
#       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